Skip to content

How does one thread wait on several channels at once?

Level: 201 · anyone who wants the first of two results, or a result or a timeout

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: Go's select waits on any number of channel operations and takes whichever is ready first, choosing at random among several — and it is the construct the other languages most conspicuously lack: Rust's std has no select, Java and Python have to wait on one queue at a time, and the workaround everywhere is to route every source into a single channel.

The question

Two workers, two channels, and a caller that wants whichever answers first. In Go it is four lines. In Rust's std, there is no way to wait on two Receivers; crossbeam has select!, tokio has one for async. In Java, BlockingQueue has no multi-wait; in Python neither has queue.Queue. The page shows the Go version, the fan-in workaround in the others, and Go's random choice when both are ready.

What each language is expected to say

Expected answer, to be verified by the program
Rust no select in std: fan both sources into one mpsc channel; crossbeam::select! otherwise (link, not run)
Go select { case v := <-a: case v := <-b: }; with both ready, uniformly random
C poll(2) on the two pipes' file descriptors is the operating system's select
C++ fan-in into one queue with a condition variable; no library multi-wait
Java fan-in into one BlockingQueue; or CompletableFuture.anyOf for one-shot results
Python fan-in into one Queue; selectors for file descriptors; asyncio.wait for tasks

What the programs have to show

  • two workers, one at 1 s and one at 3 s: which result the caller printed first, per language
  • Go's random choice measured over a thousand rounds with both ready, as Real runs
  • the fan-in, and what it cannot do that select can: send-side selection

See also