Overview

9 Concurrency

Concurrency in Go is presented as a practical way to manage many tasks at once without making programs feel blocked or unresponsive. The chapter explains the difference between concurrency and parallelism, then shows why Go is well suited for both because it gives developers lightweight goroutines and channels while the runtime handles scheduling details. Using an RSS reader as the running example, it demonstrates how a simple synchronous approach can stall on network I/O, and how launching work in goroutines lets multiple feeds be fetched at the same time.

Because concurrent code introduces coordination problems, the chapter then focuses on the tools needed to make it reliable. It covers synchronization with wait groups and error groups so the main program can wait for work to finish and capture failures cleanly, rather than relying on crude timing delays. It also shows how mutexes and read-write mutexes protect shared data such as an article store, how context adds cancellation and timeouts to long-running operations, and how these pieces combine to keep concurrent systems safe, consistent, and easier to control.

The second half broadens into channels and common concurrency patterns. Channels are shown as typed communication paths that can be returned, passed into functions, stored in structs, read from, written to, buffered, and restricted by direction to improve safety. Building on that, the chapter demonstrates select-based coordination, worker pools for limiting load, and fan-out/fan-in for launching parallel work and merging results. It ends with advice to keep concurrency simple, prefer communication over shared memory, close channels properly, limit goroutines when needed, and use concurrency only where it clearly improves responsiveness, throughput, or scalability.

Concurrency vs Parallelism
CH09 F01 Holmes
Channels in Go are like Queues with various capacities
CH09 F02 Holmes
Worker pools ingest incoming messages across multiple processes
CH09 F03 Holmes
Fan Out / Fan In
CH09 F04 Holmes

Summary

  • Go’s concurrency model is built around goroutines and channels, making concurrent programming simple and efficient.
  • Use goroutines to run functions concurrently without managing threads directly.
  • Synchronize goroutines using tools like WaitGroup, Mutex, and the errgroup package for error handling.
  • Protect shared data with mutexes to avoid race conditions and ensure data consistency.
  • Use context.Context to manage cancellation, timeouts, and request-scoped values in concurrent operations.
  • Channels provide safe communication between goroutines and enable patterns like pipelines, worker pools, and fan-in/fan-out.
  • Buffered and directional channels help control data flow and improve throughput.
  • Worker pools and fan-in/fan-out are common concurrency patterns for scalable, efficient processing.
  • The select statement allows a goroutine to wait on multiple channels, enabling responsive and robust event loops.
  • Always close channels when done and handle errors explicitly to avoid resource leaks and silent failures.
  • Use concurrency when tasks can run independently, especially for I/O-bound, network, or parallelizable workloads.
  • Avoid unnecessary concurrency in simple, strictly ordered, or single-task programs to keep code maintainable.

FAQ

What is the difference between concurrency and parallelism in Go?Concurrency is about structuring a program so it can handle multiple tasks at once by switching between them, while parallelism means actually executing multiple tasks at the same time, usually on different CPU cores.
When should I use concurrency in a Go program?Use concurrency when your program has independent tasks that can run separately, such as handling multiple network requests, processing files, doing background work, or keeping an application responsive while waiting on I/O.
Why is the go keyword important in Go concurrency?The go keyword starts a function as a goroutine, allowing it to run concurrently with the rest of the program. This is the basic way to launch asynchronous work in Go.
Why did the goroutine example not print anything at first?Because the main function exited before the goroutine finished. When main() returns, the program ends and any running goroutines are stopped.
Why is using time.Sleep not a good way to wait for goroutines?time.Sleep is unreliable because it guesses how long work will take. A better approach is to use synchronization tools like sync.WaitGroup or errgroup.Group.
What does a sync.WaitGroup do?A WaitGroup waits for a group of goroutines to finish. You add to the counter when starting work, call Done() when each goroutine completes, and call Wait() to block until all work is done.
How is errgroup different from WaitGroup?errgroup.Group works like a WaitGroup, but it also collects errors from goroutines. If any goroutine returns an error, Wait() returns that error after the goroutines finish.
Why are mutexes needed in concurrent Go programs?Mutexes protect shared data from race conditions. They ensure only one goroutine at a time can access or modify critical data, preventing corruption and inconsistent results.
What is the purpose of channels in Go?Channels let goroutines communicate safely by sending and receiving values. They are used to coordinate work, pass data, report errors, and build patterns like pipelines, fan-in/fan-out, and worker pools.
When should I avoid using concurrency in Go?Avoid concurrency when the program is simple, when tasks must happen in a strict order, when the overhead is not worth it, or when concurrency would add complexity without clear benefit.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Go in Action, Second Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Go in Action, Second Edition ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Go in Action, Second Edition ebook for free