Go

Concurrency vs. parallelism in Go — can goroutines run in parallel with GOMAXPROCS=1?

Question 170MediumGo 1.22 to 1.25

Concurrency is about how a program is structured: independent tasks whose execution can interleave. Parallelism is about execution: several tasks running at literally the same moment on different cores. Rob Pike's phrase is "concurrency is not parallelism".

With GOMAXPROCS=1, only one goroutine executes Go code at a time, so goroutines run concurrently but not in parallel. Some things still happen alongside it:

  • Goroutines blocked in syscalls or cgo run on their own threads while the P runs other Go code.
  • The netpoller waits for I/O.
  • sysmon runs without a P.
  • GC background workers can use a fraction of the P. With a single P they run in time slices.

Gotcha: GOMAXPROCS=1 does not make racy code safe. Async preemption can switch goroutines between any two instructions, including in the middle of x++. Code has to be correct with synchronization regardless of GOMAXPROCS. Running tests with -cpu=1,4 and -race exposes these assumptions.

More on Goroutines & the Scheduler

All 35 Goroutines & the Scheduler questions