Understanding the Go Runtime: The Scheduler
5 days ago
- #GMP model
- #Concurrency
- #Go scheduler
- The Go scheduler uses the GMP model: G (goroutine), M (OS thread), and P (processor).
- Goroutines (G) are lightweight, starting with a 2KB stack, and can be recycled for efficiency.
- M represents an OS thread, executing goroutines, with a special g0 goroutine for runtime tasks.
- P is a scheduling context, holding local run queues and memory caches, enabling efficient work distribution.
- The scheduler's global state, schedt, manages shared resources like the global run queue and idle lists.
- Goroutines transition through states: _Grunnable, _Grunning, _Gwaiting, and _Gdead, managing their own state changes.
- Blocking operations like channel receives or system calls involve goroutines parking themselves.
- System calls may lead to P detachment if prolonged, allowing other goroutines to continue running.
- Stack growth and preemption (cooperative and asynchronous) ensure goroutines don't monopolize resources.
- The scheduling loop prioritizes runtime work, checks local and global queues, and employs work stealing to balance load.
- Spinning threads briefly stay active to handle new work, optimizing responsiveness without wasting CPU.
- Goroutine context switches are fast (~50-100ns), leveraging minimal state saving for efficiency.