Python中的condition是threading模块提供的条件变量工具,属于线程同步机制的一种,主要用于协调多个线程之间的执行顺序,解决线程间基于特定条件进行通信和等待的问题。

condition的核心特性
condition内部维护了一个锁和等待队列,它可以在线程不满足特定条件时让线程进入等待状态,当其他线程修改了条件并通知后,等待的线程会被唤醒重新检查条件。它提供了acquire、release方法管理锁,还有wait、notify、notify_all方法处理条件等待和通知。
condition适合解决的具体问题
1 线程间需要基于共享状态协调执行顺序
当多个线程需要依赖某个共享状态的变化来决定是否继续执行时,condition是很好的选择。比如一个线程需要等待另一个线程完成初始化操作后才能开始工作,就可以用condition来实现等待和通知逻辑。
2 生产者消费者模型场景
生产者消费者模型是condition最典型的应用场景,生产者线程生产数据放入共享队列,消费者线程从队列取数据消费,当队列满时生产者需要等待,队列空时消费者需要等待,队列状态变化后需要通知对应的线程。
下面是一个简单的生产者消费者模型示例:
import threading
import time
from queue import Queue
# 创建condition对象
condition = threading.Condition()
# 共享队列,最大容量为5
shared_queue = Queue(maxsize=5)
# 模拟生产的数据总数
total_products = 10
def producer():
"""生产者线程函数"""
for i in range(total_products):
with condition:
# 队列满时等待
while shared_queue.full():
print("队列已满,生产者等待")
condition.wait()
# 生产数据放入队列
shared_queue.put(f"产品{i}")
print(f"生产者生产了产品{i},当前队列大小:{shared_queue.qsize()}")
# 通知消费者可以消费
condition.notify()
time.sleep(0.1)
def consumer():
"""消费者线程函数"""
count = 0
while count < total_products:
with condition:
# 队列空时等待
while shared_queue.empty():
print("队列已空,消费者等待")
condition.wait()
# 从队列取数据消费
product = shared_queue.get()
print(f"消费者消费了{product},当前队列大小:{shared_queue.qsize()}")
count += 1
# 通知生产者可以生产
condition.notify()
time.sleep(0.2)
if __name__ == "__main__":
# 创建生产者和消费者线程
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)
# 启动线程
producer_thread.start()
consumer_thread.start()
# 等待线程执行完成
producer_thread.join()
consumer_thread.join()
print("所有产品生产消费完成")
3 多条件等待的复杂同步场景
如果线程需要根据多个不同的条件进行等待,condition也可以支持,只需要在wait前检查对应的条件即可,不同的条件变化后可以调用对应的notify方法唤醒等待的线程。
condition和其他同步工具的差异
和普通的锁相比,锁只能保证同一时间只有一个线程操作共享资源,无法让线程基于条件等待;和信号量相比,信号量主要控制同时访问资源的线程数量,没有条件判断和通知的机制。condition的优势是可以在条件不满足时主动让线程等待,条件满足时精准通知对应的线程,减少不必要的线程唤醒和检查。
使用condition的注意事项
- 调用
wait、notify、notify_all方法前必须先获取condition的锁,否则会抛出异常 - wait方法被唤醒后会重新获取锁,然后需要再次检查条件,因为可能存在虚假唤醒的情况,所以等待条件要用while循环判断而不是if
- notify只会唤醒一个等待的线程,notify_all会唤醒所有等待的线程,需要根据实际场景选择,避免唤醒过多线程造成性能浪费
condition是Python多线程同步中非常重要的工具,只要遇到线程需要基于共享条件协调执行顺序的场景,都可以优先考虑使用它来解决问题。