The G-M-P model
- Go course
- Expert
- Lesson 1/34
- 4 min
Learn the goroutine, machine and processor trio.
The G-M-P model
The Go scheduler works with three structures: G (goroutine: its stack and state), M (machine: an operating system thread) and P (processor: the right to run plus a local queue). For a G to run, an M must hold a P.
number of P = GOMAXPROCS (default: number of CPU cores)
number of M = as many as needed (grows for blocking syscalls)
number of G = can be hundreds of thousandsThis multiplexes millions of goroutines onto a few OS threads (M:N scheduling).
Why goroutines are cheap
A goroutine starts with a stack of about 2 KB that grows as needed, while an OS thread usually reserves 1–8 MB. Switching goroutines happens in user space without entering the kernel, so context switches are very fast.
Practice P and CPU
Compare runtime.GOMAXPROCS(0) with runtime.NumCPU() and print whether the P count is not greater than the CPU count (<=).
Starter code
package main
import (
"fmt"
"runtime"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println(runtime.GOMAXPROCS(0) <= runtime.NumCPU())
}Expected output
true
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 At most how many goroutines can run Go code at the same time?
- Always 1
- As many as GOMAXPROCS (the number of Ps) Correct answer
- Unlimited
- As many as the number of Ms
Explanation: Running Go code needs a P, and the number of Ps is GOMAXPROCS. Ms waiting in syscalls don't hold a P.
2 Read the P count
fmt.Println(runtime.____(0))
fmt.Println(runtime.GOMAXPROCS(0))
Explanation: GOMAXPROCS(0) returns the current number of Ps without changing it.
3 G, M, P
| Term | Meaning |
|---|---|
G |
Goroutine |
M |
OS thread |
P |
Run right + queue |
GOMAXPROCS |
Number of Ps |