关于Python多线程condition变量的应用
'''
所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据。
它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且它还有wait,notify,notifyAll方法。 一个简单的生产消费者模型,通过条件变量的控制产品数量的增减,调用一次生产者产品就是+1,调用一次消费者产品就会-1.
使用 Condition 类来完成,由于它也可以像锁机制那样用,所以它也有 acquire 方法和 release 方法,而且它还有
wait, notify, notifyAll 方法。
''' import threading
import queue, time, random # 产品类
class Goods:
def __init__(self):
self.count = 0 def add(self, num=1):
self.count += num def sub(self):
if self.count >= 0:
self.count -= 1 def empty(self):
return self.count <= 0 # 生产者
class Producer(threading.Thread): def __init__(self, condition, goods, sleeptime=1):
threading.Thread.__init__(self)
self.cond = condition
self.goods = goods
self.sleeptime = sleeptime def run(self):
cond = self.cond
goods = self.goods
while True:
# 锁住资源
cond.acquire()
goods.add()
print("产品数量:", goods.count, "生产者线程")
# 唤醒所有等待的线程 -> 其实就是唤醒消费者进程
cond.notifyAll()
# 解锁资源
cond.release()
time.sleep(self.sleeptime) # 消费者
class Consumer(threading.Thread):
def __init__(self, condition, goods, sleeptime=2):
threading.Thread.__init__(self)
self.cond = condition
self.goods = goods
self.sleeptime = sleeptime def run(self):
cond = self.cond
goods = self.goods
while True:
time.sleep(self.sleeptime)
# 锁住资源
cond.acquire()
# 如无产品则让线程等待
while goods.empty():
cond.wait()
goods.sub()
print("产品数量:", goods.count, "消费者线程")
# 解锁资源
cond.release()
g = Goods() c = threading.Condition() pro = Producer(c, g) pro.start() con = Consumer(c, g) con.start()
''' event 对象最好单次使用,就是说,你创建一个 event 对象,让某个线程等待这个对象,
一旦这个对象被设置为真,你就应该丢弃它。尽管可以通过 clear() 方法来重置 event 对
象,但是很难确保安全地清理 event 对象并对它重新赋值。很可能会发生错过事件、死锁
或者其他问题(特别是,你无法保证重置 event 对象的代码会在线程再次等待这个 event对象之前执行)。如果一个线程需要不停地重复使用 event 对象,你最好使用 Condition
对象来代替。下面的代码使用 Condition 对象实现了一个周期定时器,每当定时器超时的
时候,其他线程都可以监测到:
''' import threading
import time class PeriodicTimer:
def __init__(self, interval):
self._interval = interval
self._flag = 0
self._cv = threading.Condition() def start(self):
t = threading.Thread(target=self.run)
t.daemon = False
t.start() def run(self):
# Run the timer and notify waiting threads after each interval
while True:
time.sleep(self._interval)
with self._cv:
self._flag ^= 1
self._cv.notify_all() def wait_for_tick(self):
# wait for the next tick of the timer with self._cv:
last_flag = self._flag
while last_flag == self._flag:
self._cv.wait() ptimer = PeriodicTimer(2)
ptimer.start() def countdown(nticks):
while nticks > 0:
ptimer.wait_for_tick()
print('T-minus', nticks)
nticks -= 1 def countup(last):
n = 0
while n < last:
ptimer.wait_for_tick()
print('Counting', n)
n += 1 threading.Thread(target=countdown, args=(10,)).start()
threading.Thread(target=countup, args=(10,)).start()
关于Python多线程condition变量的应用的更多相关文章
- Python 多线程 Condition 的使用
Condition Condition(条件变量)通常与一个锁关联.需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例. 可 ...
- python多线程--Condition(条件对象)
Condition class threading.Condition(lock=None 这个类实现条件变量对象.条件变量允许一个或多个线程等待,知道它们被另一个线程唤醒. 如果给出了lock参数而 ...
- [Python 多线程] Condition (十)
Condition常用于生产者.消费者模型,为了解决生产者消费者速度匹配问题. 构造方法Condition(lock=None),可以传入一个Lock或RLock对象,默认RLock. 方法: acq ...
- python多线程编程
Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...
- Python多线程和Python的锁
Python多线程 Python中实现多线程有两种方式,一种基于_thread模块(在Python2.x版本中为thread模块,没有下划线)的start_new_thread()函数,另一种基于th ...
- Day9 - Python 多线程、进程
Python之路,Day9, 进程.线程.协程篇 本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线 ...
- 搞定python多线程和多进程
1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...
- python多线程几种方法实现
python多线程编程 Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程 ...
- 浅析Python多线程
学习Python多线程的资料很多,吐槽Python多线程的博客也不少.本文主要介绍Python多线程实际应用,且假设读者已经了解多线程的基本概念.如果读者对进程线程概念不甚了解,可参见知名博主 阮一峰 ...
随机推荐
- pycharm支持react
安装nodejs插件 使能node 出现下面的变化,在scope里可以定义使用的范围 创建react项目 使能eslint规则检查功能 配置前端启动脚本: https://www.jetbrains. ...
- Linux命令输出头(标题)、输出结果排序技巧
原文:http://blog.csdn.net/hongweigg/article/details/65446007 ----------------------------------------- ...
- golang 查询数据库操作
SQL.Open only creates the DB object, but dies not open any connections to the database. If you want ...
- C++MFC编程笔记day01 MFC介绍、创建MFC程序和重写消息处理
一.MFC概念和作用 1.全称Microsoft Foundation Class Library,我们称为微软基础类库,封闭了绝大部分的win32 Api函数,C++语法中的数据结构,程序的运行流程 ...
- HDU 1226 超级password
跟POJ 1465 multiple 类是.仅仅只是多了2个条件,长度不能超过500.还有就是 可能不是十进制. bfs+同余定理,就是用 mod 来判重. G++ 15ms 每次枚举一位,然后记录下 ...
- 用jquery给元素动态绑定事件及样式
网页输出的时候,可以用jquery给各种元素绑定事件,或设置样式. 之所以这样做,好处是节省代码,尤其适合元素很多,并且元素的事件对应的函数雷同的情况. 看看以下代码: <div id=&quo ...
- go11---方法method
package main /* 方法method Go 中虽没有class,但依旧有method 通过显示说明receiver来实现与某个类型的组合 只能为同一个包中的类型定义方法 Receiver ...
- android7.0 编译问题及解决【转】
本文转载自:http://blog.csdn.net/zhangmingbao2016/article/details/52699182 注意:Linux操作系统上编译Android 7.0必须使用o ...
- luence全文检索(简介)
刚开始做全文检索也是找了很多资料但是网上的都不是很齐全luence是个很不多的工具 Lucene4.0的官网文档:http://lucene.apache.org/core/4_0_0/core/ov ...
- attr 和 prop的区别和使用
一. attr和prop的区别 要想弄清楚attr和prop的区别,就要先搞清楚js中使用DOM方法获取设置属性和使用对象方法获取设置属性的区别. 在javascript中使用DOM方法设置获取属性值 ...