← Questions
Bounded blocking queue for producer and consumer threads
0
I was asked this
No reports yet. Sign in to say where you were asked it.
Implement a first-in, first-out queue with a fixed capacity that any number of producer and consumer threads share. A thread that cannot make progress must sleep, not spin. The point is the synchronisation, so build it from a mutex and condition variables (or your language's monitor), not a ready-made concurrent queue.
Interface
Unless you agree on a different interface with the interviewer, assume:
-
BlockingQueue(capacity: int)—capacity >= 1. -
put(item) -> None— waits while the queue is full, then appends at the tail. -
take() -> item— waits while the queue is empty, then removes and returns the head.
Example
q = BlockingQueue(2)
put("a"); put("b")
put("c") -> blocks: the queue is full
take() -> "a" (in another thread; the blocked put now adds "c")
take() -> "b"
take() -> "c"
take() -> blocks until someone puts
Constraints
- Items leave in the order they arrived.
- Apart from waiting,
putandtakeare O(1).
Clarifying questions
- Is the queue bounded? On a full queue, should
putblock, fail or drop? - Are timed variants needed (
offer(item, timeout),poll(timeout))? - Is there a shutdown path so blocked consumers can exit?
- Which language and threading library?
What a strong answer covers
- One lock around the buffer and its count, with a stated invariant; a ring buffer or deque.
- Two conditions, "not full" and "not empty", and which operation signals which.
- A
whileloop around every wait, and why a singleifis unsafe (spurious wakeups, a competitor taking the item first). - Signal-one versus signal-all, and the lost-wakeup or deadlock risk of the wrong choice with a shared condition.
- Edge cases: capacity 1, many more producers than consumers, shutdown while threads are blocked.
- What a mutex and condition variable do underneath (atomic instructions, sleeping in the kernel).
Follow-ups
- Add
offer(item, timeout)andpoll(timeout), keeping the total wait bounded across early wakeups. - Add
close(): consumers drain what is left and then stop, producers fail fast. - With one shared condition and signal-one, build an interleaving where every thread ends up asleep.
- One lock for both ends versus separate
putandtakelocks: what does the two-lock design gain, and what keeps it correct?
No official answer yet. Write yours on the right and run it.
Nothing published yet.
Sign in to submit your code; every attempt is kept here.
Write and test your solution herePython in your browser, the question's tests level by level, every submission kept for you.Sign in to start coding
