A concurrency model defines how multiple computations execute and coordinate. Go makes concurrency a language-level concern rather than an optional library or configurable framework. Its design follows communicating sequential processes: independent processes communicate by passing messages instead of sharing memory. section 1.4
Concurrency manages progress across multiple tasks, while parallelism performs tasks simultaneously, typically on separate processors or cores. Go supplies goroutines and channels, while the runtime handles scheduling and execution. section 9.0
A practical Go concurrency design combines:
- Goroutines for running functions concurrently without directly managing threads. section 9.7
- Channels for safe communication, including pipelines, worker pools, and fan-in/fan-out patterns. section 9.7
- WaitGroup, mutex, errgroup, and context.Context for synchronization, shared-data protection, error handling, cancellation, timeouts, and request-scoped values. section 9.7
- select, buffered channels, and directional channels for responsive event loops and controlled data flow. section 9.7
Independent chores
Baking a chicken, doing laundry, and sending an email illustrate concurrent progress: the oven and washing machine can operate while the email is sent. In Go, independent work can run in goroutines and coordinate through channels rather than requiring direct thread management. section 9.0
Use concurrency for independent, especially I/O-bound, network, or parallelizable work. Avoid it for simple, strictly ordered, or single-task programs; always handle errors and channel closure to prevent leaks and silent failures. section 9.7

