博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python多线程--Condition(条件对象)
阅读量:6902 次
发布时间:2019-06-27

本文共 3365 字,大约阅读时间需要 11 分钟。

Condition

class threading.Condition(lock=None

这个类实现条件变量对象。条件变量允许一个或多个线程等待,知道它们被另一个线程唤醒。
如果给出了lock参数而不是None,则它必须是LcokRLock对象,并以它作为底层的锁。否则将默认创建一个RLock对象。
Condition遵循上下文管理协议。
方法:
acquire(*args)
获取锁。这个方法调用底层锁的相应方法。

release()

释放锁。这个方法调用底层锁的相应方法。

wait(timeout=None)

线程挂起,等待被唤醒(其他线程的notify方法)或者发生超时。调用该方法的线程必须先获得锁,否则引发RuntimeError
该方法会释放底层锁,然后阻塞,直到它被另一个线程中的相同条件变量的notify()notify_all()方法唤醒,或者发生超时。一旦被唤醒或超时,它会重新获取锁并返回。
返回值为True,如果给定timeout并发生超时,则返回False

wait_for(predicate, timeout=None)

等待知道条件变量的返回值为Truepredicate应该是一个返回值可以解释为布尔值的可调用对象。可以设置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 threadingimport timenum = 0con = 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没钱了-回老家

转载于:https://www.cnblogs.com/thunderLL/p/9838984.html

你可能感兴趣的文章
原 2017/5 JavaScript基础6--- 对象
查看>>
Python 列表、元组、字典t的常用方法
查看>>
MYSQL groupby使用方法。
查看>>
如何将ppt转换成pdf
查看>>
PowerDesigner连接MySQL数据库
查看>>
文件格式转换控件LEADTOOLS ePrint Professional
查看>>
ORACLE常见的六种RMAN恢复测试
查看>>
(Portal 开发读书笔记) Personalization
查看>>
SRCNN 实验细节
查看>>
Java多线程第二节-线程的基本使用
查看>>
界面控件Essential Studio for ASP.NET Web Forms 2017 v3发布丨附下载
查看>>
教你制作属于自己的CentOS 6.4一键自动化安装ISO镜像光盘
查看>>
线上 mysql 主库配置文档
查看>>
Java web部署目录结构和web.xml作用
查看>>
负载均衡DR(direct routing)模式
查看>>
Python中list的遍历
查看>>
Linux下查看内存等硬件信息
查看>>
mysql 登录权限
查看>>
Java之内部类
查看>>
怎样使用python帮助手册
查看>>