Condition 是 Python 中支持线程间条件等待与通知的同步原语,基于锁+等待队列实现,需用 while 循环检查条件以防虚假唤醒,典型用于生产者-消费者模型。

Condition 是 Python 中用于线程间复杂协作的同步原语,它封装了 Lock(或 Rlock)并增加了 wait()、notify() 和 notify_all() 机制,适合实现“等待某条件成立再继续执行”的场景,比如生产者-消费者模型。
Condition 的核心逻辑:锁 + 条件等待队列
Condition 内部持有一个可重入锁(默认是 Rlock),所有操作(acquire、release、wait、notify)都必须在持有该锁的前提下进行。关键点在于:
-
wait()会自动释放锁,并将当前线程挂起,加入等待队列;被notify()唤醒后,会重新尝试获取锁,成功后才从wait()返回; -
notify()和notify_all()不释放锁,也不立即唤醒线程——只是标记等待队列中的一个(或全部)线程为“可唤醒”,真正唤醒发生在当前线程释放锁之后; - **条件检查必须在
while循环中进行**,不能用if,防止虚假唤醒(spurious wakeup)或条件在唤醒后又被其他线程修改。
典型用法:生产者-消费者模式
这是 Condition 最常见的实践场景。生产者生成数据并通知消费者,消费者等待有数据可用才处理:
import threading import time import randombuffer = [] buffer_size = 5 cond = threading.Condition()
def producer(): for i in range(10): time.sleep(random.uniform(0.1, 0.5)) item = f"item-{i}" with cond: # 自动 acquire & release while len(buffer) >= buffer_size: cond.wait() # 等待缓冲区有空位 buffer.append(item) print(f"Produced: {item}, buffer size: {len(buffer)}") cond.notify() # 唤醒一个等待的消费者
def consumer(): for _ in range(10): with cond: while len(buffer) == 0: cond.wait() # 等待缓冲区有数据 item = buffer.pop(0) print(f"Consumed: {item}, buffer size: {len(buffer)}") cond.notify() # 唤醒一个等待的生产者(可选)
启动线程
threading.Thread(target=producer).start() threading.Thread(target=consumer).start()
使用 Condition 的关键注意事项
with cond:是推荐写法,确保锁的正确获取与释放;手动调用cond.acquire()/cond.release()容易出错;wait()必须在已持有锁的前提下调用,否则抛出RuntimeError;notify()只唤醒一个线程,但无法指定唤醒谁;若需精确控制,应结合其他逻辑(如状态标记+多次 notify);- 多个条件共存时(如“有数据”和“有空位”),建议用同一个 Condition,但用不同循环条件判断,避免混用
notify()导致逻辑错乱。Condition vs Lock vs Event vs Semaphore
简单对比帮助选型:
立即学习“Python免费学习笔记(深入)”;
- Lock:只保证互斥,不支持等待/通知;
- Event:适合“单次广播通知”(如启动信号),不带锁,不能区分多个等待者;
- Semaphore:适合资源计数(如连接池),但不关心具体条件是否满足;
- Condition:唯一支持“在锁保护下等待某个业务条件成立”的原语,适用于需要双向协调的场景。










