前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >31.python 线程条件变量Condition

31.python 线程条件变量Condition

作者头像
猿说编程[Python和C]
修改于 2021-04-19 06:39:32
修改于 2021-04-19 06:39:32
1.8K00
代码可运行
举报
文章被收录于专栏:猿说编程猿说编程
运行总次数:0
代码可运行

对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition.

一.线程条件变量Condition相关函数介绍

acquire() —  线程锁,注意线程条件变量Condition中的所有相关函数使用必须在acquire()/release() 内部操作;

release() — 释放锁,注意线程条件变量Condition中的所有相关函数使用必须在acquire() /release() 内部操作;

wait(timeout) —  线程挂起(阻塞状态),直到收到一个notify通知或者超时才会被唤醒继续运行(超时参数默认不设置,可选填,类型是浮点数,单位是秒)。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError;

notify(n=1) —  通知其他线程,那些挂起的线程接到这个通知之后会开始运行,缺省参数,默认是通知一个正等待通知的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError,notify()不会主动释放Lock;

notifyAll() —  如果wait状态线程比较多,notifyAll的作用就是通知所有线程;

二.线程条件变量Condition原理

在前面的文章已经介绍过互斥锁,主要作用是并行访问共享资源时,保护共享资源,防止出现脏数据。python 条件变量Condition也需要关联互斥锁,同时Condition自身提供了wait/notify/notifyAll方法,用于阻塞/通知其他并行线程,可以访问共享资源了。可以这么理解,Condition提供了一种多线程通信机制,假如线程1需要数据,那么线程1就阻塞等待,这时线程2就去制造数据,线程2制造好数据后,通知线程1可以去取数据了,然后线程1去获取数据。

三.线程条件变量Condition使用

案例一:成语接龙

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:何以解忧
@Blog(个人博客地址): https://www.codersrc.com/
 
@File:python_.py
@Time:2019/10/21 21:25
 
@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
"""
 
# 导入线程模块
import threading
 
# 创建条件变量condition
con = threading.Condition()
 
def thread_one(name):
    # 条件变量condition 线程上锁
    con.acquire()
 
    print("{}:成语接龙准备好了吗".format(name))
    # 唤醒正在等待(wait)的线程
    con.notify()
 
    # 等待对方回应消息,使用wait阻塞线程,等待对方通过notify唤醒本线程
    con.wait()
    print("{}:一干二净".format(name))
    # 唤醒对方
    con.notify()
 
    # 等待消息答应
    con.wait()
    print("{}:一天就知道看抖音美女,给你来个简单点的,来了:毛手毛脚".format(name))
    # 唤醒对方
    con.notify()
 
    # 等待消息答应
    con.wait()
    print("{}:哟哟哟,不错不错!".format(name))
    # 唤醒对方
    con.notify()
 
    # 条件变量condition 线程释放锁
    con.release()
 
def thread_two(name):
    # 条件变量condition 线程上锁
    con.acquire()
 
    # wait阻塞状态,等待其他线程通过notify唤醒本线程
    con.wait()
    print("{}:准备好了~开始吧!".format(name))
    # 唤醒对方
    con.notify()
 
    # 等待消息答应
    con.wait()
    print("{}:净你妹啊,没法接...来个简单点的...".format(name))
    # 唤醒对方
    con.notify()
 
    # 等待消息答应
    con.wait()
    print("{}:嘿,这个我知道:脚踏实地".format(name))
    # 唤醒对方
    con.notify()
 
    con.release()
 
if __name__ == "__main__":
 
    # 创建并初始化线程
    t1 = threading.Thread(target=thread_one,args=("A"))
    t2 = threading.Thread(target=thread_two,args=("B"))
 
    # 启动线程 -- 注意线程启动顺序,启动顺序很重要
    t2.start()
    t1.start()
 
    # 阻塞主线程,等待子线程结束
    t1.join()
    t2.join()
 
 
    print("程序结束!")

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A:成语接龙准备好了吗
B:准备好了~开始吧!
A:一干二净
B:净你妹啊,没法接...来个简单点的...
A:一天就知道看抖音美女,给你来个简单点的,来了:毛手毛脚
B:,这个我知道:脚踏实地
A:哟哟哟,不错不错!
程序结束!

案例二:生产者与消费者模式,以吃火锅为例:一盘老肉片有10块肉,吃完了又重新往锅里加….

生产者:往锅里加老肉片,每次加一盘(10块);

消费者:吃煮熟的肉片,没吃一片,肉片数量减一,吃完为止;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 导入线程模块
import threading
import time
 
# 创建条件变量condition
con = threading.Condition()
meat_num = 0
 
def thread_consumers():
    # 条件变量condition 线程上锁
    con.acquire()
    
    # 全局变量声明关键字 global
    global meat_num
    meat_num = 0
 
    # 等待肉片下锅煮熟
    con.wait()
    while True:
        print("我来一块肉片...")
        meat_num -= 1
        print("剩余肉片数量:%d"%meat_num)
        time.sleep(0.5)
        if meat_num == 0:
            # 肉片吃光了,通知老板添加肉片
            print("老板,再来一份老肉片...")
            con.notify()
            # 肉片吃光了,等待肉片
            con.wait()
 
    # 条件变量condition 线程释放锁
    con.release()
 
 
def thread_producer():
    # 条件变量condition 线程上锁
    con.acquire()
    # 全局变量声明关键字 global
    global meat_num
 
    # 肉片熟了,可以开始吃了
    meat_num = 10
    print("肉片熟了,可以开始吃了...")
    con.notify()
    while True:
        # 阻塞函数,等待肉片吃完的通知
        con.wait()
        meat_num = 10
        # 添加肉片完成,可以继续开吃
        print("添加肉片成功!当前肉片数量:%d"%meat_num)
        time.sleep(1)
        con.notify()
 
    con.release()
 
 
if __name__ == "__main__":
    # 创建并初始化线程
    t1 = threading.Thread(target=thread_producer)
    t2 = threading.Thread(target=thread_consumers)
 
    # 启动线程 -- 注意线程启动顺序,启动顺序很重要
    t2.start()
    t1.start()
 
    # 阻塞主线程,等待子线程结束
    t1.join()
    t2.join()
 
    print("程序结束!")

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
肉片熟了,可以开始吃了...
我来一块肉片...
剩余肉片数量:9
我来一块肉片...
剩余肉片数量:8
我来一块肉片...
剩余肉片数量:7
我来一块肉片...
剩余肉片数量:6
我来一块肉片...
剩余肉片数量:5
我来一块肉片...
剩余肉片数量:4
我来一块肉片...
剩余肉片数量:3
我来一块肉片...
剩余肉片数量:2
我来一块肉片...
剩余肉片数量:1
我来一块肉片...
剩余肉片数量:0
老板,再来一份老肉片...
添加肉片成功!当前肉片数量:10
我来一块肉片...
剩余肉片数量:9
我来一块肉片...
剩余肉片数量:8
我来一块肉片...
剩余肉片数量:7
.............

注意:

1.全局变量要声明关键字 global

2.注意线程的启动顺序,这个很重要;

四.重点总结

注意线程互斥锁Lock/线程事件Event/线程条件变量Condition三者的区别,场景不同,使用方式也不同,前两者一般可以作为简单的线程交互,线程条件变量Condition可以用于比较复杂的线程交互!

猜你喜欢:

1.python线程创建和参数传递

2.python线程互斥锁Lock

3.python线程事件Event

4.python return逻辑判断表达式

转载请注明猿说Python » python条件变量Condition

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/11/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【说站】python线程中Condition的原理
1、Python条件变量Condition需要关联互斥锁,同时Condition本身提供了wait、notify、notifyAll方法。
很酷的站长
2022/11/23
3940
【说站】python线程中Condition的原理
python 多线程 条件condition(并行编程 6)
class Consumers(threading.Thread): def init(self): threading.Thread.init(self)
用户5760343
2019/07/30
4330
Python使用Condition对象实现多线程同步
使用Condition对象可以在某些事件触发后才处理数据或执行特定的功能代码,可以用于不同线程之间的通信或通知,以实现更高级别的同步。在内部实现上,Condition对象总是与某种锁对象相关联。 Condition对象除了具有acquire()和release()方法之外,还有wait()、wait_for()、notify()、notify_all()等方法: wait(timeout=None)方法会释放锁,并阻塞当前线程直到超时或其他线程针对同一个Condition对象调用了notify()/noti
Python小屋屋主
2018/04/16
1.2K0
python的进程与线程
  进程是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间)。比如用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间。当用户再次点击IE浏览器,又启动了一个进程,操作系统将为新的进程分配新的独立的地址空间。多进程就是“多任务”,就像使用电脑时同时打开浏览器上网、打开播放器听歌、后台还默默运行着杀毒软件一样。现代操作系统如Mac OS X,UNIX,Linux,Windows等都支持多进程,每启动一个进程,操作系统便为该进程分配一个独立的内存空间。
步履不停凡
2019/08/23
7110
Python 多线程 multithr
【Python】python 多线程两种实现方式 目前python提供了几种多线程实现方式 thread,threading,multithreading ,其中thread模块比较底层,而threading模块是对thread做了一些包装,可以更加方便的被使用。 2.7版本之前python对线程的支持还不够完善,不能利用多核CPU,但是2.7版本的python中已经考虑改进这点,出现了multithreading 模块。threading模块里面主要是对一些线程的操作对象化,创建Thread的class。一般来说,使用线程有两种模式:
py3study
2020/01/06
4370
2018年8月25日多线程编程总结
PYTHON 本身也支持多任务处理,并且提供了如下的操作方式 多线程多任务处理机制   (比较常用) 多进程多任务处理机制   (不常用,大型项目开发或者系统开发会用) 协程多任务处理机制       (不常用)
武军超
2018/09/27
3940
python(五)
创建线程对象以后,可以调用它的 start()方法来启动,该方法自动调用该类对象的 run()方法。
赤蓝紫
2023/01/02
2320
python(五)
python之线程、进程、协程
上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。
菲宇
2019/06/13
5630
python3--线程,锁,同步锁,递归锁,信号量,事件,条件和定时器,队列,线程池
这个99又赋值给n,进程变量就是99,所以每次都是赋值操作,赋值了100次,最终结果99,这样还是出现数据不安全的情况
py3study
2018/08/02
3.1K0
Python学习记录-多进程和多线程
狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
py3study
2020/01/07
7890
Python自学成才之路 线程间协作 lock,condition,event的使用
多线程并发时会出现线程安全问题,如果不解决线程并发安全问题可能会让程序出现不可预料的情况。python提供了一些工具包来解决多线程安全问题,下面介绍其中常见的工具。
我是李超人
2020/09/08
1K0
Python之线程
操作系统线程理论 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。正是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出
新人小试
2018/04/12
1.4K0
Python之线程
Python多线程-手慢无的真相
我们常说的「手慢无」其实类似多线程同时竞争一个共享资源的结果,要保证结果的唯一正确性,而这让我们从线程(Python)慢慢说起……
唔仄lo咚锵
2021/09/14
5360
Python多线程-手慢无的真相
python基本 -- threading多线程模块的使用
python多线程编程,一般使用thread和threading模块。thread模块想对较底层,threading模块对thread模块进行了封装,更便于使用。所有,通常多线程编程使用threading模块。
lpe234
2020/07/27
4K0
Python3 与 C# 并发编程之~ 线程篇2
其实以前的 Linux中是没有线程这个概念的, Windows程序员经常使用线程,这一看~方便啊,然后可能是当时程序员偷懒了,就把进程模块改了改(这就是为什么之前说Linux下的多进程编程其实没有Win下那么“重量级”),弄了个精简版进程==> 线程(内核是分不出 进程和线程的,反正 PCB个数都是一样)
逸鹏
2018/09/07
6420
Python3 与 C# 并发编程之~ 线程篇2
python笔记11-多线程之Condition(条件变量)
前言 当小伙伴a在往火锅里面添加鱼丸,这个就是生产者行为;另外一个小伙伴b在吃掉鱼丸就是消费者行为。当火锅里面鱼丸达到一定数量加满后b才能吃,这就是一种条件判断了。 这就是本篇要讲的Condition(条件变量) 一、Condition Condition(条件变量)通常与一个锁关联。需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例。 可以认为,除了Lock带有的锁定池外,Condition还包含一个等待池,池中的线程处于状态图中
上海-悠悠
2018/04/08
1.5K0
python-多线程
如某个子线程的daemon属性为False(默认情况),主线程结束时会检测该子线程是否结束并等待它结束后再退出。若为True,则该子线程不管有没有运行玩,都会随主线程一起结束。
luxuantao
2021/02/24
2850
Python多线程学习
1、  函数式:调用thread模块中的start_new_thread()函数来产生新线程。如下例:
流柯
2018/08/30
3370
Python线程之threading
线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。进程是资源分配的最小单位,线程是CPU调度的最小单位,每一个进程中至少有一个线程,线程可与属于同一进程的其它线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。
py3study
2020/01/13
3680
python3 多线程编程
线程是CPU分配资源的基本单位。但一个程序开始运行,这个程序就变成了一个进程,而一个进程相当于一个或者多个线程。当没有多线程编程时,一个进程也是一个主线程,但有多线程编程时,一个进程包含多个线程,包括主线程。使用线程可以实现程序的并发。
py3study
2020/01/03
1.1K0
相关推荐
【说站】python线程中Condition的原理
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文