liveBook · Manning

Condition variable

As explained in Software Design for Python Programmers

A condition object is a synchronization object that lets threads wait for a predicate on shared state and be notified when that predicate may have changed.

A condition variable synchronizes threads around a predicate on shared state. It combines mutex protection with signaling: a thread waits while the predicate remains true, and another thread notifies when the shared state may have changed. section 16.4.1 section 16.6

The classic use is a bounded producer–consumer queue. Producers must wait when the queue is full; consumers must wait when it is empty. Both operations acquire the same condition before inspecting or changing the queue. section 16.4 section 16.4.1

Use the condition in a wait–modify–notify cycle:

  • Acquire the condition before examining the shared state. section 16.4.1
  • Wait inside a while loop when the predicate is true, such as queue-full or queue-empty; waiting releases the condition. section 16.4.1
  • Modify the shared resource while still holding the condition. section 16.4.1
  • Notify waiting threads after making the relevant state available, such as after making a queue not empty or not full. section 16.4

Bounded queue

A producer enters `with queue.condition`, waits while `queue.is_full()`, enters a value, and notifies consumers when the queue becomes nonempty. A consumer uses the complementary sequence: it waits while `queue.is_empty()`, removes a value, and notifies producers when space becomes available. After waking, each thread reacquires the condition and checks the predicate again because another thread may have changed the queue first. section 16.4.2 section 16.6

Figure 16.8 Simultaneously, multiple producers enter values into the bounded queue and multiple consumers remove values from the queue. The queue—the shared resource—has limited capacity.
A diagram of a diagram of a group of people

AI-generated content may be incorrect.

A bounded-queue diagram shows producers and consumers competing over one shared resource with limited capacity. section 16.4

Figure 16.9 The producer and consumer threads each attempt to acquire queue.condition at the top of its loop. The condition object synchronizes the producer and consumer threads. The producer threads loop to enter values into the shared bounded queue, and the consumer threads loop to remove values from the queue. A producer thread cannot enter a value into the queue when the queue is full. A consumer thread cannot remove a value from an empty queue.
A diagram of a process

AI-generated content may be incorrect.

A synchronization diagram traces the producer and consumer loops, including acquisition, waiting, queue access, and notification. section 16.4.1

How Software Design for Python Programmers covers it

How deep it goes
Explains acquisition, predicate loops, release during waiting, reacquisition, rechecking, critical regions, and notification.
Examples
Uses a Python bounded queue with multiple producers, multiple consumers, capacity limits, notifications, and zero-value end sentinels.
What it assumes
Assumes mutex and semaphore basics while reinforcing mutual exclusion, shared resources, critical regions, and thread coordination.
What you can do after
Apply it via Python's threading.Condition to coordinate protected access and waiting threads around shared-state predicates.
How it connects
Connects mutexes, semaphores, events, critical regions, bounded queues, producer–consumer systems, race conditions, and deadlocks.

Also explained in

Compare how 7 books explain condition variable →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Software Design for Python Programmers. The section links point to the parts of the book it draws on.