python多线程--Condition(条件对象)
Condition
class threading.Condition(lock=None
这个类实现条件变量对象。条件变量允许一个或多个线程等待,知道它们被另一个线程唤醒。
如果给出了lock
参数而不是None
,则它必须是Lcok
或RLock
对象,并以它作为底层的锁。否则将默认创建一个RLock
对象。
Condition
遵循上下文管理协议。
方法:
acquire(*args)
获取锁。这个方法调用底层锁的相应方法。
release()
释放锁。这个方法调用底层锁的相应方法。
wait(timeout=None)
线程挂起,等待被唤醒(其他线程的notify
方法)或者发生超时。调用该方法的线程必须先获得锁,否则引发RuntimeError
。
该方法会释放底层锁,然后阻塞,直到它被另一个线程中的相同条件变量的notify()
或notify_all()
方法唤醒,或者发生超时。一旦被唤醒或超时,它会重新获取锁并返回。
返回值为True
,如果给定timeout
并发生超时,则返回False
。
wait_for(predicate, timeout=None)
等待知道条件变量的返回值为True
。predicate
应该是一个返回值可以解释为布尔值的可调用对象。可以设置timeout
以给定最大等待时间。
该方法可以重复调用wait()
,直到predicate
的返回值解释为True
,或发生超时。该方法的返回值就是predicate
的最后一个返回值,如果发生超时,返回值为False
。
如果忽略超时功能,该方法大致相当于:
while not predicate():
con.wait()
它与wait()
的规则相同:调用前必须先获取锁,阻塞时释放锁,并在被唤醒时重新获取锁并返回。
notify(n=1)
默认情况下,唤醒等待此条件变量的一个线程(如果有)。调用该方法的线程必须先获得锁,否则引发RuntimeError
。
该方法最多唤醒n个等待中的线程,如果没有线程在等待,它就是要给无动作的操作。
注意:要被唤醒的线程实际上不会马上从wait()
方法返回(唤醒),而是等到它重新获取锁。这是因为notify()
并不会释放锁,需要线程本身来释放(通过wait()
或者release()
)
notify_all()
此方法类似于notify()
,但唤醒的时所有等待的线程。
生产者与消费者 -- Condition版
场景:生产者一次性生产5个商品(生产过程中不可购买),之后通知消费者抢购,当商品卖完后,由消费者通知生产者开始生产。
# -*- coding:utf-8 -*-
import threading
import time
num = 0
con = threading.Condition()
class Producer(threading.Thread):
"""生产者"""
def run(self):
global num
# 获取锁
con.acquire()
while True:
num += 1
print('生产了1个,现在有{0}个'.format(num))
time.sleep(1)
if num >= 5:
print('已达到5个,不再生产')
# 唤醒消费者
con.notify()
# 等待-释放锁;被唤醒-获取锁
con.wait()
# 释放锁
con.release()
class Customer(threading.Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.money = 7
def run(self):
global num
while self.money > 0:
# 由于场景是多个消费者进行抢购,如果将获取锁操作放在循环外(如生产者),
# 那么一个消费者线程被唤醒时会锁住整个循环,无法实现另一个消费者的抢购。
# 在循环中添加一套"获取锁-释放锁",一个消费者购买完成后释放锁,其他消费者
# 就可以获取锁来参与购买。
con.acquire()
if num <= 0:
print('没货了,{0}通知生产者'.format(
threading.current_thread().name))
con.notify()
con.wait()
self.money -= 1
num -= 1
print('{0}消费了1个, 剩余{1}个'.format(
threading.current_thread().name, num))
con.release()
time.sleep(1)
print('{0}没钱了-回老家'.format(threading.current_thread().name))
if __name__ == '__main__':
p = Producer(daemon=True)
c1 = Customer(name='Customer-1')
c2 = Customer(name='Customer-2')
p.start()
c1.start()
c2.start()
c1.join()
c2.join()
运行结果:
生产了1个,现在有1个
生产了1个,现在有2个
生产了1个,现在有3个
生产了1个,现在有4个
生产了1个,现在有5个
已达到5个,不再生产
Customer-1消费了1个, 剩余4个
Customer-2消费了1个, 剩余3个
Customer-1消费了1个, 剩余2个
Customer-2消费了1个, 剩余1个
Customer-1消费了1个, 剩余0个
没货了,Customer-2通知生产者
生产了1个,现在有1个
生产了1个,现在有2个
生产了1个,现在有3个
生产了1个,现在有4个
生产了1个,现在有5个
已达到5个,不再生产
Customer-1消费了1个, 剩余4个
Customer-2消费了1个, 剩余3个
Customer-1消费了1个, 剩余2个
Customer-2消费了1个, 剩余1个
Customer-1消费了1个, 剩余0个
没货了,Customer-2通知生产者
生产了1个,现在有1个
生产了1个,现在有2个
生产了1个,现在有3个
生产了1个,现在有4个
生产了1个,现在有5个
已达到5个,不再生产
Customer-1消费了1个, 剩余4个
Customer-2消费了1个, 剩余3个
Customer-2消费了1个, 剩余2个
Customer-1消费了1个, 剩余1个
Customer-1没钱了-回老家
Customer-2消费了1个, 剩余0个
没货了,Customer-2通知生产者
生产了1个,现在有1个
生产了1个,现在有2个
生产了1个,现在有3个
生产了1个,现在有4个
生产了1个,现在有5个
已达到5个,不再生产
Customer-2消费了1个, 剩余4个
Customer-2没钱了-回老家
python多线程--Condition(条件对象)的更多相关文章
- Java多线程——Condition条件
简介 Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signa ...
- python线程condition条件锁应用实例
import time import threading # 吃火锅鱼丸 guo = [] suo = threading.Condition() #条件锁 # 生产者负责生产 class Produ ...
- 关于Python多线程condition变量的应用
''' 所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据. 它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且 ...
- Python 多线程 Condition 的使用
Condition Condition(条件变量)通常与一个锁关联.需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例. 可 ...
- [Python 多线程] Condition (十)
Condition常用于生产者.消费者模型,为了解决生产者消费者速度匹配问题. 构造方法Condition(lock=None),可以传入一个Lock或RLock对象,默认RLock. 方法: acq ...
- Python多线程-Barrier(障碍对象)
Barrier(parties, action=None, timeout=None) 每个线程通过调用wait()尝试通过障碍,并阻塞,直到阻塞的数量达到parties时,阻塞的线程被同时全部释放. ...
- Python多线程-Event(事件对象)
Event 事件对象管理一个内部标志,通过set()方法将其设置为True,并使用clear()方法将其设置为False.wait()方法阻塞,直到标志为True.该标志初始为False. 方法: i ...
- python多线程-Semaphore(信号对象)
Semaphore(value=1) Semaphore对象内部管理一个计数器,该计数器由每个acquire()调用递减,并由每个release()调用递增.计数器永远不会低于零,当acquire() ...
- java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)
Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...
随机推荐
- python 安装教程
1) 安装python2.7,下载地址 https://www.python.org/downloads/ ----2.7 安装完成后,设置环境变量加入path --d:/ruanjian/p ...
- excel2007自定义菜单项学习
参考: http://club.excelhome.net/thread-1288002-1-1.html http://club.excelhome.net/thread-709306-1-1.ht ...
- 振动器(Vibrator)
package com.wwj.serviceandboardcast; import android.app.Activity; import android.app.Service; impo ...
- font-style字体设置
用到一些字体找起来很麻烦,扒了一些 未测试 HTML,CSS,font-family:中文字体的英文名称 宋体 SimSun黑体 SimHei微软雅黑 Microsoft YaHei微软正黑体 Mic ...
- 20155205 2016-2017-2 《Java程序设计》第6周学习总结
20155205 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 在Java中,输入串流代表对象为Java.io.InputStream实例,输出串流 ...
- Linux上的TIME_WAIT和tcp_fin_timeout
当Linux服务器的TIME_WAIT过多时,通常会想到去修改参数降低TIME_WAIT时长,以减少TIME_WAIT数量,但Linux并没有提供这样的接口,除非重新编译内核. Linux默认的TIM ...
- 禁止浏览器缓存js
方法:在js文件后加上数学随机数; Math.random() 比如:源代码为 <script src="./js/lib/require/require.js" data- ...
- 1.gil全局解释器锁, 2. 死锁与递归锁 3. 信号量 4. Event事件 5. 线程queue
gil本质就是一把互斥锁,相当于执行权限,每个进程都会存在一把gil,同一进程内的多个线程必须抢到gil 之后才能使用cpython解释器来执行自己的代码,同一进程下的多线程不能并行,但可以实现并发 ...
- H5总结
1.新增的语义化标签: <nav>: 导航 <header>: 页眉 <footer>: 页脚 <section>:区块 <article> ...
- ORACLE ERP consolidation流程(一)
原文地址:ORACLE ERP consolidation流程(一) 作者:wolfyuan ORACLE EBS by transaction consolidation的详细流程(一)[@more ...