详细说明Python中的Condition类

互斥锁Lock和RLock只能提供简单的加锁和释放锁等功能,它们的主要作用是在多线程访问共享数据时,保护共享数据,防止数据被脏读脏写,保证数据和关键代码的完整性。在此基础上,Python提供了Condition类,Condition类不仅自身依赖于Lock和RLock,即具有它们的阻塞特性,此外还提供了一些有利于线程通信,以及解决复杂线程同步问题的方法,它也被称作条件变量

一、Condition类提供的方法

构造方法:

__init__(self,lock=None)

1)从Condition类的构造方法可以看出,Condition类总是与一个锁相关联。在创建一个Condition类的同时就应该传入Condition类需要绑定的Lock对象;

2)另外,如果不指定lock参数,那么Python会自动创建一个与之绑定的Lock对象。

acquire(timeout)

调用Condition类关联的Lock/RLock的acquire()方法。

release()

调用Condition类关联的Lock/RLock的release()方法。

wait(timeout)

1)线程挂起,直到收到一个notify通知或者等待时间超出timeout才会被唤醒;

2)注意:wait()必须在已获得Lock的前提下调用,否则会引起RuntimeError错误。

notify(n=1)

1)唤醒在Condition的waiting池中的n(参数n可设置,默认为1)个正在等待的线程并通知它,受到通知的线程将自动调用acquire()方法尝试加锁;

2)如果waiting池中有多个线程,随机选择n个唤醒;

3)必须在已获得Lock的前提下调用,否则将引发错误。

notify_all()

唤醒waiting池中的等待的所有线程并通知它们。

二、实例详解

生产者消费者问题

问题:

假设有一群生产者(Producer)和一群消费者(Consumer)通过一个市场来交互产品。生产者的”策略“是如果市场上剩余的产品少于500个,那么就生产50个产品放到市场上;而消费者的”策略“是如果市场上剩余产品的数量多于100个,那么就消费10个产品。

代码:

import threading
from time import sleep

#商品
product = 500
#条件变量
con = threading.Condition(threading.Lock())

#生产者类
#继承Thread类
class Producer(threading.Thread):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        global product
        while True:
            #如果获得了锁
            if con.acquire():
                #处理产品大于等于500和小于500的情况
                if product >= 500:
                    #如果大于等于500,Producer不需要额外操作,于是挂起
                    con.wait()
                else:
                    product += 50
                    message = self.name + " produced 50 products."
                    print(message)
                    #处理完成,发出通知告诉Consumer
                    con.notify()
                #释放锁
                con.release()
                sleep(1)
#消费者类
#继承Thread类
class Consumer(threading.Thread):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        global product
        while True:
            #如果获得了锁
            if con.acquire():
                #处理product小于等于100和大于100的两种情况
                if product <= 100:
                    #如果小于等于100,Consumer不需要额外操作,于是挂起
                    con.wait()
                else:
                    product -= 10
                    message = self.name + " consumed 10 products."
                    print(message)
                    #处理完成,发出通知告诉Producer
                    con.notify()
                #释放锁
                con.release()
                sleep(1)
                
def main():
    #创建两个Producer
    for i in range(2):
        p = Producer('Producer-%d'%i)
        p.start()
    #创建三个Consumer
    for i in range(3):
        c = Consumer('Consumer-%d'%i)
        c.start()

if __name__ == '__main__':
    main()

运行结果:

Consumer-0 consumed 10 products.
Consumer-1 consumed 10 products.
Consumer-2 consumed 10 products.
Producer-0 produced 50 products.
Consumer-0 consumed 10 products.
Consumer-1 consumed 10 products.
Consumer-2 consumed 10 products.
Producer-0 produced 50 products.
Consumer-1 consumed 10 products.
Consumer-0 consumed 10 products.
Consumer-2 consumed 10 products.
Consumer-1 consumed 10 products.
......
  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值