A producer acquires the mutex first, then waits on the empty-slot semaphore. The buffer is currently full. What happens?
ADeadlock: the producer holds the mutex while blocked on the semaphore, preventing any consumer from acquiring the mutex to free a slot
BThe producer waits on the semaphore and automatically releases the mutex while blocked
CA consumer signals the empty-slot semaphore from outside the critical section, unblocking the producer
DThe OS detects the contention and suspends the producer temporarily without causing deadlock
This is the canonical deadlock in producer-consumer implementations. The producer holds the mutex and then blocks waiting for an empty slot. But the only way an empty slot can appear is for a consumer to remove an item — which requires acquiring the mutex. The mutex is held by the blocked producer, so the consumer blocks on the mutex. Both threads are stuck forever. The fix: always acquire the counting semaphore before the mutex.
Question 2 Multiple Choice
In a condition-variable-based producer-consumer implementation, why must the wait() call always appear inside a while loop rather than an if statement?
AA while loop retries the operation automatically on failure, which is required for liveness
BSpurious wakeups and the possibility that another thread consumed the resource before this thread runs require rechecking the condition after every wakeup
CThe monitor semantics require that wait() be called at least twice before a thread proceeds
DIf statements cannot appear inside synchronized code due to OS scheduling constraints
Two hazards require the while loop. First, spurious wakeups: some OS implementations allow threads to wake from wait() without being explicitly signaled. Second, even with a valid signal, another thread may have been scheduled first and already consumed the item this thread was woken to process. The while loop re-evaluates the condition after every wakeup and re-waits if the condition is still not satisfied. A bare if statement causes a bug that is hard to reproduce under low load but catastrophic under contention.
Question 3 True / False
In the semaphore-based producer-consumer solution, the mutex is acquired after the counting semaphore (not before) to prevent the producer from blocking while holding the mutex.
TTrue
FFalse
Answer: True
Correct — the ordering rule is: wait on the counting semaphore first, then acquire the mutex. The counting semaphore acts as a gate: it ensures the thread only proceeds when a slot or item is actually available. Only after passing that gate does the thread take the mutex to modify the shared buffer. Reversing the order (mutex first) creates the deadlock described in the first question.
Question 4 True / False
A producer and consumer operating on a bounded buffer seldom need synchronization as long as they access different cells in the buffer at the same time.
TTrue
FFalse
Answer: False
Even when accessing different cells, synchronization is required. The read and write pointers (indices into the buffer) are shared state that both threads read and modify. Without a mutex protecting the buffer's bookkeeping, both threads might simultaneously update the same pointer, corrupting the buffer's state. Additionally, counting semaphores are needed to prevent the producer from writing to a full buffer or the consumer from reading from an empty one — neither of which is about which specific cell is accessed.
Question 5 Short Answer
Describe the deadlock that occurs when a producer acquires the mutex before waiting on the counting semaphore, and explain the rule that prevents it.
Think about your answer, then reveal below.
Model answer: If the producer acquires the mutex before waiting on the empty-slot semaphore and the buffer is full, the producer will block waiting for a slot while holding the mutex. The consumer, needing to acquire the mutex to remove an item and signal the semaphore, is blocked by the mutex. Neither thread can proceed: the producer holds what the consumer needs (the mutex) and waits for what only the consumer can provide (a free slot). The rule that prevents this: always acquire the counting semaphore before the mutex, so that a thread only takes the mutex once it is already guaranteed a valid slot or item exists.
This deadlock is a textbook example of hold-and-wait, one of the four necessary conditions for deadlock. The fix (acquiring the semaphore before the mutex) eliminates hold-and-wait for the blocking condition: the thread acquires the mutex only after the semaphore guarantees it will not need to block.