liveBook · Manning

Condition variable

As explained in Learn Concurrent Programming with Go

A condition variable is a synchronization mechanism that allows threads or goroutines to wait for a specified condition and be notified when it may hold.

A condition variable lets a goroutine stop until shared state may have changed. It complements a mutex: the mutex protects the state and the condition variable coordinates waiting, so a goroutine need not repeatedly unlock, sleep, and check again. Polling with arbitrary sleeps either wastes CPU time or delays work after the needed change has already happened. section 5.1 section 5.1.1

Use a condition variable around a predicate on shared state. Lock its associated mutex, check the predicate in a loop, and call Wait when the predicate is false. Wait atomically releases the mutex and suspends the goroutine; after Signal or Broadcast wakes it, Wait reacquires the mutex and the predicate is checked again. The loop matters because waking indicates that state may have changed, not that the condition is necessarily true. section 5.1.1 section 5.4

Figure 5.2 Common pattern for using a condition variable with a mutex

Follow the state transition: a waiting goroutine releases the mutex, an updating goroutine changes shared state and signals, then the waiter resumes and rechecks the condition. section 5.1.1

Wait until a balance can fund a withdrawal

A spending goroutine locks the condition variable’s mutex and waits while the account has less than 50. An earning goroutine locks the same mutex, adds funds, calls Signal, and unlocks. The spending goroutine resumes with the mutex held, rechecks the balance, and subtracts only when enough money is available. This prevents a negative balance without timed retrying. section 5.1.1

Choose the notification operation by the number of waiters that may proceed:

  • Use Signal to resume one suspended goroutine. Which waiter resumes is arbitrary when several goroutines are waiting. section 5.1.3
  • Use Broadcast to resume every goroutine suspended in Wait, then let each reacquire the mutex and evaluate its own condition. section 5.1.3
  • Do not treat a notification as stored work: Signal or Broadcast is missed if no goroutine is waiting. section 5.1.2

Start a game after every player arrives

Each player handler decrements a shared remaining-player count while holding the mutex. Handlers wait while the count is above zero. The last player changes it to zero and calls Broadcast, allowing every waiting handler to continue into gameplay. This is a natural fit when one state transition releases a group. section 5.1.3

Condition variables can also define richer synchronization tools. A write-preferring readers–writer lock waits readers while writers are waiting or active, and waits writers while readers or another writer are active. Broadcasting when the last reader exits or a writer exits gives blocked goroutines another chance to test their conditions, avoiding writer starvation caused by continually arriving readers. section 5.1.4 section 5.4

They are building blocks rather than only application-level coordination. A waitgroup can protect a task count with a mutex, wait while the count remains positive, and broadcast when the final Done call reduces it to zero. The same approach can support more complete custom synchronization abstractions. section 6.1.4 section 1.5.3

How Learn Concurrent Programming with Go covers it

How deep it goes
Works through Wait, Signal, Broadcast, missed notifications, multi-waiter coordination, and implementations of readers–writer locks and waitgroups.
Examples
Uses a bank balance, a multiplayer game lobby, writer starvation, and a custom waitgroup.
What it assumes
Builds on mutex-protected critical sections while introducing condition-based suspension and notification from zero.
What you can do after
Build it from scratch as a waitgroup or write-preferring readers–writer lock using a mutex, predicates, waits, and broadcasts.
How it connects
Connects mutexes, semaphores, waitgroups, readers–writer locks, starvation, channels, and CSP-style concurrency.

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 Learn Concurrent Programming with Go. The section links point to the parts of the book it draws on.