A Condition combines a lock with waiting and notification so threads can coordinate changes to a shared predicate.
Python Condition: wait for protected state, not for a notification count
Operation contract
The consumer waits until the one-element receipt slot becomes nonempty, then removes its value while holding the same condition lock. The producer writes the slot and notifies while holding that lock. wait_for rechecks the predicate after reacquiring the lock. A notification without the required state cannot make the consumer proceed; notification is a prompt to recheck, not a durable message.
Failure and ownership boundary
The timeout bounds this teaching wait and raises if no receipt arrives. It is not a whole-service deadline or a process shutdown policy. The slot has one producer and one consumer; a queue with many writers needs explicit capacity and closed-state rules. Python locks: protect the complete inventory transition, Python asyncio.Queue: backpressure and completion accounting and Python expiry exercise: separate pending, active and expired records at exact boundaries keep those contracts distinct.
Working program
from threading import Condition, Thread
condition = Condition()
slot, received = [], []
def consume():
with condition:
if not condition.wait_for(lambda: bool(slot), timeout=2):
raise TimeoutError("receipt did not arrive")
received.append(slot.pop())
consumer = Thread(target=consume)
consumer.start()
with condition:
slot.append(125)
condition.notify()
consumer.join(timeout=3)
if consumer.is_alive():
raise RuntimeError("consumer did not finish")
print("received:", received)
print("empty slot:", slot == [])Output
received: [125]
empty slot: TrueCosts and limits
This one-slot transition has bounded application storage. Scheduling and lock acquisition latency are not constant-time guarantees. wait_for releases the lock while blocked and reacquires it before returning; application work inside the lock can delay both producers and other consumers.
Common Mistakes
- Guard reads, writes and predicate checks with the same lock.
- Notify does not release the lock immediately or store a future message.
Connected lessons
Python locks: protect the complete inventory transition, Python thread pools: collect results and observe worker failures, Python asyncio.Queue: backpressure and completion accounting.
