5.2.25 · D3C++ Programming

Worked examples — std - condition_variable

2,334 words11 min readBack to topic

Everything below builds on the parent topic and leans on std::mutex, std::unique_lock, std::lock_guard, and the Producer-Consumer Pattern.


The scenario matrix

Think of a condition_variable program as having a few independent "axes". Every real situation is one cell — a combination of choices along these axes. We must hit every cell at least once.

Axis Cases to cover
Number of waiters 0 waiters · 1 waiter · N waiters
Which notify notify_one · notify_all
Order of events notify after waiter sleeps (normal) · notify before waiter sleeps (early / lost)
Predicate outcome pred true on first check · pred false → sleep · woken but still false (spurious/stolen)
Timing wait forever · wait_for timeout (deadline passes vs. arrives in time)
Degenerate / bug flag set without lock (lost wakeup) · if instead of while (stolen item) · notify with no waiter (dropped)

The nine worked examples below are each tagged [Cell: …] so you can see the matrix fill up.

Figure — std - condition_variable

Example 1 — Predicate already true (no sleep at all)


Example 2 — Predicate false, one real notify (the happy path)

Figure — std - condition_variable

Example 3 — Spurious wakeup (woken with nobody notifying)


Example 4 — N waiters, one item, notify_one (stolen wakeup)


Example 5 — N waiters, notify_all, only one item (why the while earns its keep)


Example 6 — Timed wait that times out vs. arrives in time


Example 7 — The lost-wakeup race (degenerate: flag set without the lock)

Figure — std - condition_variable

Example 8 — Real-world word problem: pizza kitchen (bounded buffer)


Example 9 — Exam twist: how many pred() evaluations for K items via K notifies?


Flashcards

With notify_all, one item, and 3 waiters, how many consumers proceed and how many re-sleep?
1 proceeds; 2 re-sleep because the while re-checks the (now false) predicate.
What does cv.wait_for return?
The final value of the predicate — true if the condition holds, false if it timed out with the condition still false.
In the lost-wakeup bug, why is the notify dropped?
It is sent while no thread is inside wait; a condition_variable has no memory, so a notify with no waiter is lost.
If the predicate is already true when wait(lk,pred) is called, how many times does the thread sleep?
Zero — the predicate is checked before sleeping, so wait returns immediately.
Why use notify_one (not notify_all) after pushing exactly one item?
Only one unit of work exists, so waking one waiter is enough; waking all just makes extras wake and re-sleep, wasting CPU.
Recall One-line summary of the whole matrix

Correctness always comes from flag + mutex + while-loop; notify is only a nudge, and every failure case (spurious, stolen, lost, timeout) is handled by re-checking the predicate under the lock.