Python线程条件对象(Condition)

在Python线程中,`threading`模块提供了条件变量`condition`来支持线程之间的复杂同步。条件变量运行一个或多个线程等待,直到另一个线程发出特定的通知信号。条件变量通常与锁(`Lock`或`RLock`)一起使用。

`threading.Condition()`的锁对象可以通过传入的方式获得,或者在缺省的情况下自动创建(此时自动创建的锁对象为递归锁对象`RLock`)。当多个条件变量需要共享同一个锁时,传入一个锁很有用。锁是条件对象的一部分,你不必单独跟踪它。

条件变量遵循上下文管理器协议,使用with语句会在它包围的代码块内获取关联的锁。

`Condition`对象的方法

  • acquire()release():获取和释放底层锁。
  • wait(timeout=None):线程等待,直到接收到通知或者超时。线程在调用wait()时会释放锁,并在被唤醒后重新获取锁。当提供了 timeout 参数且不是 None 时,它应该是一个浮点数,代表操作的超时时间,以秒为单位(可以为小数)。返回 True ,除非提供的 timeout 过期,这种情况下返回 False
  • wait_for(predicate, tomeout=None):等待,直到条件计算为真。 predicate 应该是一个可调用对象而且它的返回值可被解释为一个布尔值。可以提供 timeout 参数给出最大等待时间。这个实用方法会重复地调用 wait() 直到满足判断式或者发生超时。返回值是判断式最后一个返回值,而且如果方法发生超时会返回 False 。
  • notify():通知一个等待的线程。
  • notify_all():通知所有等待的线程。

注意: notify() 方法和 notify_all() 方法并不会释放锁,这意味着被唤醒的线程不会立即从它们的 wait() 方法调用中返回,而是会在调用了 notify() 方法或 notify_all() 方法的线程最终放弃了锁的所有权后返回。

使用场景:

线程间的协作:一个线程等待特定条件的达成,而另一个线程达成该条件并通知等待线程。

生产者-消费者模型:生产者线程生成资源并通知消费者线程使用资源。

下面展示一个如何使用condition对象实现生成者-消费者模型

import threading
import time

shared_resource = []
MAX_QUEUE_SIZE = 5
condition = threading.Condition()


def producer():
    while True:
        with condition:
            if len(shared_resource) >= MAX_QUEUE_SIZE:
                print("缓冲区已满,生产者等待")
                condition.wait()    #  等待直到队列有空间
            shared_resource.append("产品")
            print(f"生产了一个产品,当前缓冲区:{shared_resource}")
            condition.notify() # 通知消费者有新产品
            time.sleep(0.5)


def consumer():
    while True:
        with condition:
            if not shared_resource:
                print("缓冲区为空,消费者等待")
                condition.wait()  # 等待直到队列不为空
            item = shared_resource.pop(0)
            print(f"消费了一个产品:{item}, 当前缓冲区:{shared_resource}")
            condition.notify() # 通知生产者可以生产
            time.sleep(0.5)


producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()

上面主要包括生产者线程和消费者线程。生产者生成一个随机数并将其添加到队列中。如果队列已满,生产者等待;否则,生产者通知消费者有新产品可用。消费者从队列中取出一个产品。如果队列为空,消费者等待;否则,消费者通知生产者可以继续生产。

使用 while 循环检查所要求的条件成立与否是有必要的,因为 wait() 方法可能要经过不确定长度的时间后才会返回,而此时导致 notify() 方法调用的那个条件可能已经不再成立。这是多线程编程所固有的问题。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值