🔀Go deeper — read the bookA thread pool, from scratch— runnable code & full walkthrough →

multithreading · high

Producer-Consumer with Condition Variables

A bounded queue with a mutex + two condition variables: the producer blocks when full, the consumer when empty, and notify wakes the other.

🔑 Key line

mutex guards the queue; not_full blocks a full producer, not_empty an empty consumer; notify wakes them - always wait() in a while-loop.

The code

std::queue<T> q;
std::mutex m;
std::condition_variable not_full, not_empty;
void producer(T x) {
std::unique_lock lk(m);
not_full.wait(lk, [] { return q.size() < CAP; });
q.push(x);
not_empty.notify_one();
}
void consumer() {
std::unique_lock lk(m);
not_empty.wait(lk, [] { return !q.empty(); });
x = q.front();
q.pop();
not_full.notify_one();
}

What this lesson walks through

  1. 01A bounded queue shared by two threads
  2. 02Producer pushes and notifies not_empty
  3. 03One more push fills the queue
  4. 04Full -> producer blocks on not_full
  5. 05Consumer pops and notifies not_full
  6. 06Producer wakes, re-checks, pushes E
  7. 07Empty -> consumer blocks on not_empty
  8. 08The whole protocol

A producer adds items to a fixed-size queue and a consumer removes them. They coordinate with one mutex and two condition variables: not_full and not_empty.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of Producer-Consumer with Condition Variables and 100+ animated C++ interview lessons.

← Previous
Deadlock & the 4 Coffman Conditions
Next →
Spinlock with std::atomic_flag