In a producer-consumer scenario also known as Bounded-Buffer Problem, what…
2023
In a producer-consumer scenario also known as Bounded-Buffer Problem, what would be the most appropriate synchronization primitive to ensure that the consumer waits when the buffer is empty?
- A.
Spinlock
- B.
Mutex lock
- C.
Semaphore
- D.
Monitors
Attempted by 184 students.
Show answer & explanation
Correct answer: C
Concept
Solving the bounded-buffer problem needs a primitive that does two things at once: keep a running count of how many units of a resource are available, and put a thread to sleep (block it) when the count it needs has reached zero, then wake it the instant the count is restored. A primitive that only enforces mutual exclusion, or that waits by spinning on the CPU, cannot satisfy both of these at the same time.
The primitive that natively provides exactly this count-and-block behaviour is the counting semaphore: an integer value accessed only through two atomic operations - wait (decrement; block the caller if the value would go below zero) and signal (increment; wake one blocked thread).
Application to the bounded buffer
The bounded-buffer (producer-consumer) problem is solved with two counting semaphores plus one for mutual exclusion:
empty, initialised to the buffer size N - the producer waits on it before inserting, so it blocks when the buffer is full.
full, initialised to 0 - the consumer waits on it before removing, so it blocks (sleeps) exactly when the buffer is empty and is woken by the producer's signal after an insert.
mutex, a binary semaphore, guards the critical section that touches the shared buffer.
The requirement in the stem - the consumer must wait when the buffer is empty - is met precisely by the consumer performing wait on full: with full starting at 0, the very first remove blocks until a producer signals.
Contrast with the other primitives
Primitive | Why it does not fit the requirement |
|---|---|
Spinlock | Provides mutual exclusion only and waits by busy-looping on the CPU; it neither counts items nor lets a thread sleep until data arrives, so the consumer would burn CPU instead of waiting. |
Mutex lock | A pure lock/unlock for one critical section; it carries no count of buffered items, so on its own it cannot make the consumer wait specifically for the buffer to become non-empty. |
Monitors | A higher-level construct that can solve the same problem using condition variables, but the question asks for the basic primitive that natively combines a resource count with blocking - an abstraction layer rather than that primitive. |