liveBook · Manning

Concurrency

As explained in Go by Example

Concurrency is the ability to structure a program so that multiple execution activities can make progress during overlapping periods.

Concurrency structures a program as independent activities that make progress during overlapping periods. In Go, goroutines run concurrent functions, and channels communicate and synchronize their work through explicit message flow. section 1.4 section 1.4.1

Start work with goroutines

Prefixing a function call with go schedules it to run in a goroutine, so two crawl calls can proceed concurrently. Goroutines use the same function syntax as sequential code and are lightweight enough that thread pools are usually unnecessary, although repeatedly creating goroutines for tiny, frequent tasks can add overhead. section 1.4.1

Figure 1.3 The go statement before a function spawns a new goroutine that runs the given function concurrently. This figure illustrates running the crawl function concurrently in two separate goroutines.
A diagram of a graph

AI-generated content may be incorrect.

The diagram shows a go statement spawning separate goroutines for two crawl operations. section 1.4.1

The runtime scheduler multiplexes goroutines onto a smaller set of threads. When a goroutine blocks on a channel or I/O, it is parked so a ready goroutine can run; nonblocking I/O helps avoid blocking operating-system threads for I/O-bound work. Concurrency is distinct from parallelism: multiple CPU cores may run threads in parallel, but concurrent structure can also execute sequentially. section 1.4.2 section 6.9.3

A concurrent pipeline organizes work into stages:

  • Connect focused stages with channels, passing messages from producers through intermediate work to final consumers. section 6.6.1
  • Add, remove, and reuse stages independently, improving flexibility, modularity, and maintainability. section 6.6.1
  • Keep a package API synchronous when concurrency is an internal implementation choice; callers can still run synchronous functions concurrently themselves. section 6.1.2

Load-testing with a concurrent pipeline

A request client can retain its synchronous SendN API while internally piping requests through concurrent stages. With 100 requests that each take 100 ms, one worker finishes in about 10 seconds, while 10 workers finish in just over 1 second; a 25-RPS throttle limits that run to about 4 seconds. Raising concurrency eventually has diminishing returns when resources or nonparallelizable work become bottlenecks. section 6.6 section 6.9.3

How Go by Example covers it

How deep it goes
Explains goroutines, channels, scheduling, pipeline design, API hiding, and scaling limits, while deferring scheduler internals.
Examples
Demonstrates concurrent web crawling and a HIT client sending 100 requests with one or ten workers and optional RPS throttling.
What it assumes
Assumes programming fundamentals and general concepts including CPUs, memory, networks, and concurrent programming.
What you can do after
Build concurrent Go processing with goroutines, channels, and pipeline stages while keeping package APIs synchronous.
How it connects
Connects goroutines and channels with the Go scheduler, synchronous APIs, pipelines, throttling, and parallelism.

Also explained in

Compare how 23 books explain concurrency →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go by Example. The section links point to the parts of the book it draws on.