Lesson 1 / 25
Concurrency, Parallelism and the Go Scheduler
Structure versus simultaneous execution, and how goroutines get CPU time.
Concurrency is not parallelism
Concurrency is about structure: a program is composed of independently executing pieces that may overlap in time. Parallelism is about execution: work literally happening at the same instant on several CPU cores. A concurrent Go program can run on one core (the pieces interleave) or many (they run in parallel). The Go runtime uses an M:N scheduler: many goroutines (G) are multiplexed onto a smaller set of OS threads (M), and each running thread must hold a logical processor (P). The number of Ps is GOMAXPROCS, which defaults to the number of usable CPUs; newer Go releases also take container CPU limits into account on Linux (check the docs for your version). Goroutines that block on channels, locks or the network are parked cheaply instead of tying up a thread, and the scheduler is preemptive, so a tight loop cannot starve others forever.
Many goroutines, a few threads
Go multiplexes lightweight goroutines onto a small number of OS threads, so you design for concurrency and let the runtime find parallelism.
Inspecting the runtime
Reading scheduler-related values from the runtime package.
package main
import (
"fmt"
"runtime"
)
func main() {
// GOMAXPROCS(0) queries the current value without changing it.
fmt.Println("logical CPUs:", runtime.NumCPU())
fmt.Println("GOMAXPROCS: ", runtime.GOMAXPROCS(0))
fmt.Println("goroutines: ", runtime.NumGoroutine()) // at least 1: main itself
}One chef, many dishes
A single chef juggling several dishes (stir one, check another while it simmers) is concurrency. Several chefs each cooking a dish at the same time is parallelism. Go lets you write the recipe once; the kitchen decides how many chefs to use.
Quick check: What does GOMAXPROCS control?
- The size of each goroutine stack
- The maximum number of goroutines a program may create
- How many OS threads can execute Go code simultaneously (the number of Ps)
- How many channels can be open at once
Answer
How many OS threads can execute Go code simultaneously (the number of Ps) — GOMAXPROCS limits parallel execution of Go code, not the number of goroutines. Threads blocked in system calls do not count against it.