Problem Statement
Design and implement a thread-safe bounded queue that supports multiple producer and consumer threads concurrently.
Requirements:
enqueue(item)— blocks if the queue is fulldequeue()— blocks if the queue is empty- Must handle multiple producers and multiple consumers safely
- No data races, no deadlocks
Constraints
- Queue has a fixed max capacity
N - Multiple threads call
enqueueanddequeuesimultaneously - Must use mutexes and condition variables (no lock-free requirement)
- Language: C++ (but logic applies to any language)
Example
ThreadSafeQueue<int> q(5); // capacity 5
// Producer thread
q.enqueue(42); // succeeds immediately if space available
q.enqueue(43); // blocks if queue is full
// Consumer thread
int val = q.dequeue(); // blocks if queue is empty
What the Interviewer Expects
- Mutex for mutual exclusion — protect shared state (the underlying container + size)
- Two condition variables — one for "not full" (producers wait on), one for "not empty" (consumers wait on)
- Proper wait predicate — always use
whileloop (notif) to handle spurious wakeups - Notify correctly —
enqueuenotifies "not empty",dequeuenotifies "not full" - RAII locking — use
unique_locknot rawlock/unlock
Follow-ups
- What if no producer has started but all consumers are already waiting? How do you avoid permanent blocking?
- What happens when the destructor is called while threads are blocked? How do you implement graceful shutdown?
- How would you add a
try_dequeue(timeout)that gives up after a deadline? - What's the difference between
notify_one()andnotify_all()here? When would you use each? - How would you make this lock-free using atomics? What are the trade-offs?