python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 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使用
案例一:成语接龙
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:何以解忧
@Blog(个人博客地址): shuopython.com
@WeChat Official Account(微信公众号):猿说python
@Github:www.github.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("程序结束!")
输出结果:
A:成语接龙准备好了吗
B:准备好了~开始吧!
A:一干二净
B:净你妹啊,没法接...来个简单点的...
A:一天就知道看抖音美女,给你来个简单点的,来了:毛手毛脚
B:嘿,这个我知道:脚踏实地
A:哟哟哟,不错不错!
程序结束!

案例二:生产者与消费者模式,以吃火锅为例:一盘老肉片有10块肉,吃完了又重新往锅里加….
生产者:往锅里加老肉片,每次加一盘(10块);
消费者:吃煮熟的肉片,没吃一片,肉片数量减一,吃完为止;
# 导入线程模块
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("程序结束!")
输出结果:
肉片熟了,可以开始吃了...
我来一块肉片...
剩余肉片数量:9
我来一块肉片...
剩余肉片数量:8
我来一块肉片...
剩余肉片数量:7
我来一块肉片...
剩余肉片数量:6
我来一块肉片...
剩余肉片数量:5
我来一块肉片...
剩余肉片数量:4
我来一块肉片...
剩余肉片数量:3
我来一块肉片...
剩余肉片数量:2
我来一块肉片...
剩余肉片数量:1
我来一块肉片...
剩余肉片数量:0
老板,再来一份老肉片...
添加肉片成功!当前肉片数量:10
我来一块肉片...
剩余肉片数量:9
我来一块肉片...
剩余肉片数量:8
我来一块肉片...
剩余肉片数量:7
.............
注意:
1.全局变量要声明关键字 global;
2.注意线程的启动顺序,这个很重要;
四.重点总结
注意线程互斥锁Lock/线程事件Event/线程条件变量Condition三者的区别,场景不同,使用方式也不同,前两者一般可以作为简单的线程交互,线程条件变量Condition可以用于比较复杂的线程交互!
猜你喜欢:
转载请注明:猿说Python » python条件变量Condition

python线程条件变量Condition(31)的更多相关文章
- python线程的条件变量Condition的用法实例
Condition 对象就是条件变量,它总是与某种锁相关联,可以是外部传入的锁或是系统默认创建的锁.当几个条件变量共享一个锁时,你就应该自己传入一个锁.这个锁不需要你操心,Condition 类会 ...
- Python 线程同步变量,同步条件,列队
条件变量同步 有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了 ...
- 深入解析条件变量(condition variables)
深入解析条件变量 什么是条件变量(condition variables) 引用APUE中的一句话: Condition variables are another synchronization m ...
- [development][C] 条件变量(condition variables)的应用场景是什么
产生这个问题的起因是这样的: [:] <tong> lilydjwg: 主线程要启动N个子线程, 一个局部变量作为把同样的参数传入每一个子线程. 子线程在开始的十行会处理完参数. ...
- Linux组件封装(二)中条件变量Condition的封装
条件变量主要用于实现线程之间的协作关系. pthread_cond_t常用的操作有: int pthread_cond_init(pthread_cond_t *cond, pthread_conda ...
- Linux 线程 条件变量
一:条件变量 直接上最基本的两个函数,先抓主要矛盾: //等待条件 int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex ...
- [转] 条件变量(Condition Variable)详解
http://www.wuzesheng.com/?p=1668 条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A ...
- 孤荷凌寒自学python第四十二天python线程控制之Condition对象
孤荷凌寒自学python第四十二天python的线程同步之Condition对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天学习了Condition对象,发现它综合了Event对象 ...
- 条件变量(Condition Variable)详解
条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A中包含两个线程t1和t2.t1需要在bool变量test_cond ...
随机推荐
- <Machine Learning - 李宏毅> 学习笔记
<Machine Learning - 李宏毅> 学习笔记 b站视频地址:李宏毅2019国语 第一章 机器学习介绍 Hand crafted rules Machine learning ...
- Java IO编程——File文件操作类
在Java语言里面提供有对于文件操作系统操作的支持,而这个支持就在java.io.File类中进行了定义,也就是说在整个java.io包里面,File类是唯一 一个与文件本身操作(创建.删除.重命名等 ...
- 解决tortoiseSvn 访问版本库的时候一直初始化,或者无响应的问题
现象 svn访问版本库时一直提示: please wait while the repository browser is initializing 没有反应,甚至3-4分钟才会出来,即便出来也会很卡 ...
- 设计模式(十三)Visitor模式
Visitor模式可以用来把数据结构与处理分离开.通俗来说就是编写一个访问者类来访问数据结构中的元素,并把对各元素的处理交给访问者类.这样,当需要增加新的处理时,只需要编写新的访问者,然后让数据结构可 ...
- 聊一聊Java中的各种运算符
计算机之所以叫“计算机”,其最基本用途之一就是运算,对应刚刚接触Java的小伙伴而言,熟悉并掌握Java中的各种运算符及其在表达式中的运算优先级是十分必要的. 算术运算 算术运算主要用来处理数学中的加 ...
- 在虚拟机中使用DHCP动态管理主机地址
小知识 DHCP协议服务能够自动化的管理局域网内的主机IP地址,有效的提升IP地址使用率,提高配置效率,减少管理与维护成本.简而言之,就是ip地址分配. *****五星重点 所需要的服务:dhcp 下 ...
- [考试反思]0815NOIP模拟测试22
40分,15名. 1-4:120 75 70 70 35分20名...总之差距极小不想说了 昨天教练说:以后的考试还是联赛知识点,但是难度比联赛高. 没听进去,以为是对于所有人而言的,也就是T1难度变 ...
- NOIP模拟 25
分层考试第一场. 垫底. T1 lighthouse 观察到m很小,想到容斥. 正常人都想枚举子集,只有我打了搜索. 为了压行,我压缩了几句分类讨论. 压错了,原地爆炸 考场思路: 不容斥这也不可做啊 ...
- 命运Ⅰ&命运Ⅱ
upd:为啥下面的相关博文都是各种退役记(这TM怎么就相关了) 竟然被卡线了,16名,我这几次考试也是炸到了一定境界了... 前三次模拟总榜rk1,第一次分机房rk4,第二次分机房rk11,第三次分机 ...
- Redis中的键值过期操作
1.过期设置 Redis 中设置过期时间主要通过以下四种方式: expire key seconds:设置 key 在 n 秒后过期: pexpire key milliseconds:设置 key ...