buffer is a
queue data structure with a maximum capacity. In systems programming, the most
common bounded buffers hold up to
CAP characters, where
CAP is the buffer
capacity. A writer can write characters into the buffer until it is full, and
a reader can read characters out of the buffer until it is empty. This kind of
bounded buffer is used to implement pipe buffers, network socket buffers, and
other communication buffers. (We implemented a bounded buffer in the
Bounded buffers have interesting blocking behavior.
- A writer that attempts to write a character into a full buffer should block until some space is available (or the buffer is closed).
- A reader that attempts to read a character out of an empty buffer should block until some characters are available (or the buffer is closed).
Bounded buffers also have interesting synchronization behavior, because they involve multiple communicating threads or processes.
How would you use mutexes and condition variables to build a correctly-synchronized bounded buffer?
1. How many condition variables, and corresponding to which conditions?
2. How many mutexes?
3. Sketch out some pseudocode.
If you have time, implement your plan in our bounded buffer code,
Condition variable operations
std::condition_variable_any cv; std::mutex m; cv.wait(m); // In one atomic step, effectively: // (1) Unlocks `m` via `m.unlock()` // (2) Blocks until another thread calls `cv.notify*()`. // Then, when this thread is woken up, it re-locks `m` via `m.lock()` // before returning. cv.notify_all(); // Wakes up all threads blocked in `cv.wait()`.
We recommend always using
std::condition_variable has some surprising