Reading — step 1 of 5
Learn
Channels
A channel is a typed conduit between goroutines: one side sends values in, the other receives them out, and the runtime handles every bit of the synchronization. Channels are how Go programs move both data and ownership between concurrent parts.
Blocking is the feature
On an unbuffered channel a send blocks until a receiver is ready, and vice versa — the two goroutines meet. That rendezvous is the synchronization: when your send completes, you know the other side has the value. A buffered channel decouples the two sides by up to cap values; sends block only when the buffer is full.
If every goroutine ends up blocked, the runtime kills the program with fatal error: all goroutines are asleep - deadlock! — you will meet this message the first time you forget a close.
close: how receivers learn it is over
close is a one-way signal from the sender meaning "no more values." After the channel drains, receives return the zero value with ok == false, and — most usefully — range exits:
Three things panic: sending on a closed channel, closing a channel twice, closing a nil channel. Hence the ownership idiom: only the sender closes, and defer close(ch) at the top of the sending goroutine makes that happen on every exit path.
Direction in the type
Function signatures can restrict a channel to one direction:
Misusing the channel becomes a compile error — the cheapest bug report you will ever get.
Pipelines
Chaining stages with channels is the canonical Go pattern: each stage receives, transforms, and sends onward.
When the producer closes its channel, the next stage's range ends, its defer close fires, and the shutdown ripples cleanly down the whole pipeline. (Waiting on several channels at once needs select — that is lesson 5.1.)
Your exercise
Exactly this pipeline: a producer goroutine sends each input int into a; a squarer goroutine ranges over a and sends n * n into b; main sums what arrives on b. The starter already has both goroutines and both defer close lines — you fill in the two sends.
Mistakes the grader will catch:
- Forgetting to square. Fill the second TODO with
b <- nand input1 2 3 4 5prints15; the expected output is55(1+4+9+16+25). - Leaving a TODO as
_ = n. Nothing is ever sent; the channels just close, and you print0. - Removing a
defer close. The downstreamrangenever terminates:fatal error: all goroutines are asleep - deadlock!instead of output.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…