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
- 01
Sender
goch <- valueWaits for a receiver
- 02
Rendezvous
gomake(chan int)No queued value slot
- 03
Receiver
govalue := <-chWaits 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.
Read and predict
package main
func main() {
ready := make(chan string)
ready <- "hello"
println(<-ready)
}What happens, and would a buffer of one change it?
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.