Concurrency
25 steps in 7 sets of Go.
The reason people pick Go. Goroutines, channels, select, context for cancellation, then the sync package for when channels are the wrong tool, and finally the patterns that combine them.
Twenty-five steps, the longest Go tour here. Concurrency is cheap enough in Go that you reach for it casually, which is both the appeal and the way people get into trouble.
Goroutines
- Goroutines and WaitGroupStarting concurrent work and waiting for it.
- WaitGroup.GoGo 1.25 added Go, which does the Add and Done for you.
- The race, and the fixAn unguarded increment loses updates; the race detector finds it.
Channels
- Unbuffered channelsAn unbuffered send blocks until another goroutine receives: that is the handshake.
- Buffered channelsA buffer lets a sender run ahead, up to its capacity.
- ChannelsTyped pipes that carry values between goroutines.
- Channel directionA parameter type can restrict a channel to sending or receiving.
select
- selectWaiting on whichever channel is ready first.
- select with defaultA default case makes select non-blocking, which is how you poll.
- TimeoutsA select against time.After bounds how long you wait.
Context
- Context and cancellationPropagating deadlines and cancellation signals.
- Contexts with a deadlineA context carries cancellation down a call tree, and every wait respects it.
- Context valuesA context can carry request-scoped values, keyed by an unexported type.
Synchronization
- MutexesGuarding shared state that goroutines both touch.
- RWMutexMany readers or one writer, when reads dominate.
- sync.OnceExactly-once initialization, safe from any number of goroutines.
- Atomics and sync.OnceLock-free counters, and one-time initialization.
- Atomic typesThe typed atomics carry their own memory, so a mutex is unnecessary.
Patterns
- Worker poolsA fixed set of goroutines draining a job channel.
- Limiting concurrencyA buffered channel used as a token bucket caps how many run at once.
- Fan-inMerging several channels into one, closing the result when all are done.
- PipelinesEach stage reads a channel and returns one, so stages compose.
- Graceful shutdownA done channel, closed once, tells every worker to stop.
Encore
- crawler.goFetch several URLs concurrently and report each result.
- pipeline.goA cancellable three-stage pipeline with bounded concurrency.