Classical Synchronization Problems • Producer-Consumer ProblemMedium⏱️ ~2 min
Bounded Buffer Solution
Key Insight
In real systems, buffers have limited capacity. When the buffer is full, producers must wait until a consumer removes an item.
Bounded Buffer (capacity N)
The Third Semaphore
spaces: Initialized to N (buffer capacity). Producer decrements before adding. If zero (buffer full), producer blocks. Consumer increments after removing, signaling a space is available.
Symmetry
Producer waits on spaces, signals items. Consumer waits on items, signals spaces. Beautiful symmetry. Each thread consumes one resource and produces another.
Why Bounded Buffers Matter
Memory: Unbounded buffers can grow forever if producers are faster than consumers. Bounded buffers cap memory usage.
Backpressure: When buffer fills, producers slow down. This natural flow control prevents overload.
Pattern: Three semaphores: mutex (=1), items (=0), spaces (=N). Producer: wait(spaces), wait(mutex), add, signal(mutex), signal(items). Consumer: opposite.
💡 Key Takeaways
✓Third semaphore spaces tracks empty slots. Initialized to buffer capacity N.
✓Producer waits spaces (block if full), then mutex. Consumer waits items (block if empty), then mutex.
✓After consuming, signal spaces. After producing, signal items. Symmetric flow.
✓Invariant: items + spaces = N always. Together they track buffer state without reading it.
✓This is the standard bounded buffer / blocking queue implementation pattern.
📌 Examples
1Buffer size 10: spaces starts at 10. After 10 produces, spaces = 0 and next producer blocks.
2One produce, one consume: spaces goes 10 to 9 to 10. Items goes 0 to 1 to 0.