go · level 3 · unit 6 · lesson 1
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
A carries a stop signal to every goroutine that holds it.
A context carries a stop signal through your program. Start from context.Background(), an empty context that is never cancelled. context.WithCancel(parent) hands back a new context and a cancel function. Calling cancel() closes the context's Done() channel, the same broadcast trick as a done channel.
A goroutine handed the context watches for with case <-ctx.Done(): in its select, and stops. Afterwards ctx.Err() says why: context.Canceled, which prints with American spelling as context canceled.
Always call cancel, even when the work finished by itself; defer cancel() is the usual way. Calling it twice is harmless.
package main
import (
"context"
"fmt"
)
func countSheep(ctx context.Context, out chan<- int) {
for n := 1; ; n++ {
select {
case out <- n:
case <-ctx.Done():
return
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
sheep := make(chan int)
go countSheep(ctx, sheep)
fmt.Println(<-sheep, <-sheep, <-sheep)
cancel()
fmt.Println("stopped:", ctx.Err())
} for n := 1; ; n++ has no condition, so it counts on until something stops it.
guess first
Cancel twice, then wait on Done. What prints?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
package main
import (
"context"
"fmt"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
fmt.Println(ctx.Err())
cancel()
cancel()
<-ctx.Done()
fmt.Println(ctx.Err())
}
your turn
Your turn. Count some sheep, then stop.
Choose how many sheep to count, then fill in the call that tells countSheep to stop.
output
press run to see what happens
fix it
The gates never close. Can you fix it?
output
press run to see what happens
- Both goroutines wait forever. Which context are they really watching?
context.Background()is never cancelled, so itsDonechannel never closes.- Pass
ctxinstead ofcontext.Background()on line 17.
nailed it
your goroutines stop when you say so. :D
context.WithCancelgives a context and acancelfunction.- Watch
ctx.Done()in aselectand stop when it closes. - Always call
cancel, usually withdefer cancel().
new words in your collection
- context
- cancellation
This lesson isn’t saved. A free account remembers every lesson you finish.