Skip to content

What stops a fast producer from filling memory?

Level: 201 · anyone whose queue grew until the process was killed

Stub — a question and its expected answers, not yet a lesson. No program behind this page has been written or run, so nothing on it has been through the check that backs every finished page. The table is what the finished lesson is expected to find, and every cell is unverified until a program prints it. (Not machine-checked here.)

One line: A bounded queue makes a producer that is faster than its consumer wait, which is backpressure, and an unbounded one lets it run ahead until the difference between the two rates has consumed all the memory there is; the bound is not a tuning parameter but the thing that keeps the program's memory finite.

The question

A producer makes an item every millisecond; the consumer takes ten to handle one. After a second, an unbounded queue holds nine hundred items. After a minute, fifty-four thousand. The page runs both for a fixed time and reports the queue's peak length: the bound, or a number that grows with the run. Then it shows what the producer does when it is blocked — and the third option, dropping.

What each language is expected to say

Expected answer, to be verified by the program
Rust sync_channel(8) blocks the sender at eight; channel() grows without limit
Go make(chan T, 8) blocks at eight; there is no unbounded channel, on purpose
C a pipe blocks the writer at the kernel's buffer size
C++ a hand-built queue with a capacity and two condition variables
Java ArrayBlockingQueue(8) blocks put; offer returns false instead; LinkedBlockingQueue grows
Python Queue(maxsize=8) blocks put; put_nowait raises Full

What the programs have to show

  • the fast producer, slow consumer, one second: peak queue length under a bound of eight and under no bound
  • the blocked producer's wall time, and the dropped-item count under offer/put_nowait
  • a Real runs fence of memory after a minute unbounded

See also