Skip to content

Unbuffered channel

Category: Communication · Status: stub · Lessons: chapter 05, Message passing (planned)

One line: A channel with no buffer: a send waits until a receiver takes the value, so every message is also a meeting of the two tasks.

Also called: synchronous channel, rendezvous channel, synchronized channel.

How it connects

flowchart LR
  n_bounded_channel["Buffered and bounded channels"]
  n_channel["Channel"]
  n_csp["Communicating sequential processes"]
  n_unbuffered_channel["Unbuffered channel"]
  n_bounded_channel ---|vs| n_unbuffered_channel
  n_csp -->|uses| n_unbuffered_channel
  n_unbuffered_channel -->|is a| n_channel
  classDef center stroke-width:3px
  class n_unbuffered_channel center
  classDef outside stroke-dasharray: 4 3
  class n_bounded_channel,n_channel,n_csp outside

In each language

Rust sync_channel(0), a rendezvous channel: each send does not return until a receive is paired with it
Go make(chan T): with the capacity zero or absent, communication succeeds only when sender and receiver are both ready
Java SynchronousQueue: every insert waits for a remove, the queue has no capacity at all, and its docs compare it to the rendezvous channels of CSP
Python no rendezvous queue: maxsize=0 makes a queue.Queue infinite, not unbuffered
Kotlin Channel.RENDEZVOUS (capacity 0): no buffer, so send suspends until a receive arrives, and vice versa
Erlang and Elixir none: signals between processes are asynchronous ↗; a synchronous request is built on top, as GenServer.call does by waiting for the reply

Where to read more