WaitingOnCondition详解

发布时间:2023-05-19

一、什么是WaitingOnCondition

WaitingOnCondition是Python Thread模块中的一个机制,它提供了一种让线程暂停和恢复执行的方法。它的基本原理是:线程在执行的时候,判断某个条件是否满足,如果条件不满足,就停止执行,等待某个事件的发生,直到事件发生之后,线程才会继续执行下去。 我们通常使用多线程的目的是为了提高程序的执行效率和吞吐量,但有时候我们需要控制线程的执行顺序和执行依赖关系,必须要等待某个条件满足之后才能继续执行,这时我们就需要用到WaitingOnCondition。

二、WaitingOnCondition的核心方法

WaitingOnCondition有两个核心方法:wait()notify()

1. wait()

wait()用来让线程在等待某个条件满足的时候暂停执行,并且释放持有的锁,让其他线程有机会获得锁并修改线程等待的条件。如果等待的条件不满足,线程会进入等待状态,并一直等待到其它线程调用notify()方法来通知它条件已经发生了变化,或者设置timeout参数,如果超过指定的时间还没有被唤醒,就会自动唤醒。

2. notify()

notify()用来唤醒等待在某个条件上的线程,通知它条件已经发生了变化。如果有多个线程在同一个条件上等待,notify()只能唤醒其中一个线程(不保证唤醒哪个),而notifyAll()方法则会唤醒所有等待在该条件上的线程。

三、WaitingOnCondition的使用示例

下面是一个非常简单的使用WaitingOnCondition机制的例子。

# 导入线程模块
import threading
# 创建锁
lock = threading.Lock()
# 创建条件
condition = threading.Condition(lock)
def func_1():
    with lock:
        print("func_1获得了锁")
        condition.wait()
        print("func_1被唤醒了")
def func_2():
    with lock:
        print("func_2获得了锁")
        condition.notify()
        print("func_2发送了通知")
# 创建线程
t1 = threading.Thread(target=func_1)
t2 = threading.Thread(target=func_2)
# 启动线程
t1.start()
t2.start()
# 等待线程结束
t1.join()
t2.join()

在这个例子中,我们创建了一个锁和一个条件,然后创建了两个线程,分别是func_1func_2,线程func_1在执行过程中调用了condition.wait()方法,进入了等待状态,并释放了持有的锁。线程func_2在执行过程中调用了condition.notify()方法,通知func_1线程等待的条件已经发生了变化。 这个例子非常简单,只是说明了使用WaitingOnCondition机制的基本方法。实际上,在实际应用中,WaitingOnCondition机制还可以结合多线程的等待队列、超时等待等功能来使用,从而实现更加复杂的线程交互和协同的逻辑。完整代码可以参考以下示例:

# 导入线程模块
import threading
import time
# 创建锁
lock = threading.Lock()
# 创建条件
condition = threading.Condition(lock)
# 等待队列
wait_queue = []
def producer():
    i = 0
    while i < 5:
        with lock:
            print("producer获得了锁")
            wait_queue.append(i)
            condition.notify()
            print("producer发送了通知")
            i += 1
            time.sleep(1)
def consumer():
    while True:
        with lock:
            print("consumer获得了锁")
            while len(wait_queue) == 0:
                print("consumer没有等待队列")
                condition.wait(timeout=5)
                print("consumer等待结束")
            item = wait_queue.pop(0)
            print("consumer获取了%d" % item)
# 创建线程
t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)
# 启动线程
t1.start()
t2.start()
# 等待线程结束
t1.join()
t2.join()

在这个例子中,我们创建了一个生产者线程和一个消费者线程。生产者线程会把数字0~4依次加入到等待队列中,并且每次加入一个数字后,都会调用condition.notify()方法通知消费者线程等待队列已经增加了一个元素。消费者线程会不断的从等待队列中获取元素,并处理。 在消费者线程的执行过程中,如果等待队列为空,它会调用condition.wait(timeout=5)方法,等待5秒,如果还没有其它线程调用了notify()方法通知它,它就会自动被唤醒,并且继续等待。这种机制在实际应用中非常常见,可以实现复杂的线程交互和协同的逻辑。