Classical Synchronization ProblemsProducer-Consumer ProblemMedium⏱️ ~2 min

Solving Producer-Consumer with Semaphores

Key Insight
We need two semaphores: a mutex to protect buffer access, and a counting semaphore to track available items.
Unbounded Buffer Solution
mutex = 1, items = 0Producercreate itemmutex.wait()buffer.add(item)mutex.signal()items.signal()Consumeritems.wait()mutex.wait()item = buffer.get()mutex.signal()

How It Works

Producer: Creates item outside critical section, then locks mutex, adds to buffer, unlocks mutex, signals that a new item exists.

Consumer: Waits for an item to exist (items semaphore), then locks mutex, removes item, unlocks mutex, processes item outside critical section.

Why Two Semaphores?

mutex: Ensures only one thread modifies the buffer at a time.

items: Counts available items. Consumer blocks when zero. Producer increments after adding.

Order Matters In Consumer

Consumer waits on items first, then mutex. If reversed (mutex then items), consumer holds mutex while waiting for items. Producer cannot add because it needs mutex. Deadlock!

Rule: Always wait on condition semaphore before mutex. Release in reverse order.
💡 Key Takeaways
Two semaphores: mutex (initial 1) protects buffer, items (initial 0) counts available items.
Consumer waits on items first, then acquires mutex. This prevents deadlock.
Producer signals items after adding. Consumer waits on items before removing.
The order matters: check availability before locking, release lock before signaling.
Multiple producers and consumers can use this pattern: symmetric, generalizes to any count.
📌 Examples
1items semaphore tracks buffer contents. Positive = items available. Negative = consumers waiting.
2Processing outside the mutex: event.process() runs after releasing mutex, maximizing concurrency.
← Back to Producer-Consumer Problem Overview
Solving Producer-Consumer with Semaphores | Producer-Consumer Problem - System Overflow