CodeBlanks Logo Icon CodeBlanks

The G-M-P model

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 thousands

This 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

main.go
package main

import (
    "fmt"
    "runtime"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
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

Question
fmt.Println(runtime.____(0))
Answer
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

All lessons in Expert