Sobes.tech
Middle

What is runtime and how does the scheduler work?

sobes.tech AI

Answer from AI

The runtime in Go is the environment in which Go programs are executed. It includes:

  • Memory management: Garbage collector automatically manages memory allocation and deallocation.
  • Scheduler: Manages the execution of goroutines on operating system threads.
  • System calls: Provides an interface for interacting with the operating system.
  • Synchronization primitives: Channels, mutexes, and other mechanisms for coordinating goroutines.

The Go scheduler implements the M:N model (multiple goroutines on multiple OS threads). Its main components:

  • G (Goroutine): A lightweight thread of execution, essentially an abstraction over a function.
  • M (Machine): An OS thread on which Go programs run.
  • P (Processor): A logical processor associated with an OS thread. It holds a local runnable queue of goroutines.

Scheduler working principle:

  1. Goroutines (G) are created and added to a global or local runnable queue.
  2. OS threads (M) are associated with logical processors (P). The default number of P equals the number of CPU cores (GOMAXPROCS).
  3. P takes a goroutine from its local queue. If the local queue is empty, P tries to "steal" goroutines from another P's queue or from the global queue.
  4. M executes the goroutine.
  5. When a goroutine blocks (e.g., reading from a channel with no data or performing a system call), M detaches from P, and P becomes available to run another goroutine. The blocked goroutine is put into waiting. When the block is released, the goroutine becomes runnable again and is re-queued.
  6. If M blocks in a system call, it does not hold P. A new M can be created or an existing one can be used so that P can continue executing other goroutines.

This approach allows efficient use of CPU resources and easy scaling of parallel tasks, hiding the complexity of OS thread management from the developer.

// Example of creating a goroutine
func myFunc() {
	// Goroutine code
}

func main() {
	go myFunc() // Launch goroutine
	// Main program continues execution in parallel
}