typestar

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.

Start this tour

Goroutines

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

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.

The other Go tours