Concurrency · 3 MIN READ

An unbuffered channel is a meeting

Say what blocks, and for how long, on a channel with no buffer.

A send on an unbuffered channel does not complete until a receiver takes the value, and a receive does not complete until a sender provides one. It is a rendezvous, not a mailbox.

This is why the classic first Go deadlock is one line long: send on an unbuffered channel from the only goroutine there is, and nobody can ever arrive to meet it. The runtime notices that every goroutine is asleep and stops the program, which is a much better failure than a silent hang.

SEE THE IDEA

A send and a receive meet at one point

  1. 01

    Sender

    go
    ch <- value

    Waits for a receiver

  2. 02

    Rendezvous

    go
    make(chan int)

    No queued value slot

  3. 03

    Receiver

    go
    value := <-ch

    Waits for a sender

Completion of the exchange establishes synchronization between the participating goroutines.

In practice

Use an unbuffered channel when handing over a value should wait until a receiver is ready. Reason about both sides before launching work: a send performed before any receiver can run has nowhere to go. A channel communicates values and coordinates timing at the same time.

Watch out

Sending and then receiving on the same unbuffered channel in one goroutine blocks at the send.

Official reference ↗

Read and predict

go
package main

func main() {
	ready := make(chan string)
	ready <- "hello"
	println(<-ready)
}

What happens, and would a buffer of one change it?

Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.