Skip to content

Condition variable

Category: Synchronization · Status: stub · Lessons: chapter 04, Waiting for each other (planned)

One line: Lets a thread that holds a lock sleep until another thread signals that what it waits for may now be true; wake-ups can be spurious, so the condition is checked again in a loop.

Also called: condvar, spurious wakeup, guarded block, wait and notify.

How it connects

flowchart LR
  n_busy_waiting["Busy waiting"]
  n_condition_variable["Condition variable"]
  n_monitor["Monitor"]
  n_mutex["Mutex"]
  n_synchronization["Synchronization"]
  n_busy_waiting ---|or| n_condition_variable
  n_condition_variable -->|is a| n_synchronization
  n_condition_variable -->|uses| n_mutex
  n_monitor -->|uses| n_condition_variable
  classDef center stroke-width:3px
  class n_condition_variable center
  classDef outside stroke-dasharray: 4 3
  class n_busy_waiting,n_monitor,n_mutex,n_synchronization outside

In each language

Rust Condvar: wait is susceptible to spurious wakeups, and wait_while checks the predicate for you
Go sync.Cond, whose docs say most simple uses are better off with channels: Broadcast is like closing one, Signal like sending on one
C cnd_wait returns when signalled or on a spurious wake-up
C++ std::condition_variable::wait may wake spuriously; the overload taking a predicate loops for you
Java A Condition from a Lock, or Object.wait inside synchronized; both permit spurious wakeups
Python threading.Condition; wait_for automates the condition check
C# Monitor.Wait with Pulse and PulseAll, called by the thread that owns the lock
JavaScript Atomics.wait and Atomics.notify on shared memory; wait cannot be used on the main thread
The operating system POSIX pthread_cond_wait: spurious wakeups may occur

Where to read more