Step 1 of 5 · Reading · ~4 min
Learn
Goroutines and Channels
Channels
A channel is a typed pipe between goroutines. You will pass values between goroutines, end a stream, and chain goroutines into pipelines and worker pools.
In Goroutines each worker wrote its own slot and main read them after Wait. Here goroutines hand values to each other directly, and the hand-off is the synchronization.
Send, receive, block
On an unbuffered channel a send waits for a receiver and a receive waits for a sender; the two meet, then both continue. A buffered channel, make(chan int, 2), holds up to 2 values: sends block only when it is full, receives only when it is empty.
fatal error: all goroutines are asleep - deadlock!
With every goroutine blocked, the runtime aborts with that unrecoverable error; the grader reports a runtime error.
close and the end of a stream
close(ch) tells receivers no more values are coming. Buffered values stay readable; after they drain, a receive returns the zero value at once, and the second result says which case you got:
for v := range c receives until the channel is closed and drained. Forget the close and it waits forever: the deadlock above.
Only the sending side closes. Sending on a closed channel panics (send on closed channel), and so does closing twice. A receiver cannot know a sender is finished, so it never closes. Here close is an ordinary call after the loop; the Defer lesson shows a safer spelling.
Direction in the type
Inside shout, in <- "x" does not compile; Go 1.13 reports invalid operation: in <- "x" (send to receive-only type <-chan string). A plain chan string converts to either direction when you pass it.
Generators and pipelines
A generator starts a goroutine and returns the channel it feeds. A stage takes a <-chan and returns a new one; closing cascades, because when a stage's input closes its range ends and it closes its output.
Fan-out: several workers, one jobs channel
Several goroutines can range over the same channel; each value goes to exactly one of them, and which one is not deterministic. Tag every result with its index and store it by index.
The closer has its own goroutine. If main called wg.Wait() before reading out, the workers would block sending results nobody receives, Done would never run, and you would get the deadlock. Waiting on two channels at once needs select, a later lesson.
Common mistakes
- A missing
close. The next stage'srangenever ends:all goroutines are asleep - deadlock!instead of output. - Closing in the wrong place. Closing an input channel, or closing while another goroutine can still send, panics with
send on closed channel. - Two stages reading the same channel by accident. Each value reaches only one of them, so output silently goes missing. A stage that must see every value needs its own input.
Your exercise
Build a concurrent prime sieve: a generator goroutine feeds the numbers 2 up to L, and each prime that reaches the front of the chain gets its own filter goroutine in line behind it. The starter fixes the signatures; you write the bodies and the wiring. The likeliest slip is a missing close.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…