Sobes.tech
Middle

Wat is runtime en hoe werkt de scheduler?

sobes.tech AI

Antwoord van AI

De runtime in Go is de omgeving waarin Go-programma's worden uitgevoerd. Het omvat:

  • Geheugenbeheer: De garbage collector beheert automatisch de toewijzing en vrijgave van geheugen.
  • Scheduler: Beheert de uitvoering van goroutines op besturingssysteemthreads.
  • Systeemaanroepen: Biedt een interface voor interactie met het besturingssysteem.
  • Primitieven voor synchronisatie: Kanalen, mutexen en andere mechanismen om goroutines te coördineren.

De Go-scheduler implementeert het M:N-model (veel goroutines op veel OS-threads). De belangrijkste componenten:

  • G (Goroutine): Een lichte uitvoeringsdraad, in wezen een abstractie van een functie.
  • M (Machine): Een besturingssysteemthread waarop Go-programma's worden uitgevoerd.
  • P (Processor): Een logische processor die verbonden is met een OS-thread. Het houdt een lokale runnable-wachtrij voor goroutines.

Werking van de scheduler:

  1. Goroutines (G) worden gemaakt en toegevoegd aan een globale of lokale runnable-wachtrij.
  2. OS-threads (M) worden gekoppeld aan logische processors (P). Het standaard aantal P is gelijk aan het aantal CPU-kernen (GOMAXPROCS).
  3. P pakt een goroutine uit zijn lokale wachtrij. Als de lokale wachtrij leeg is, probeert P goroutines te stelen van een andere P of van de globale wachtrij.
  4. M voert de goroutine uit.
  5. Wanneer een goroutine geblokkeerd raakt (bijvoorbeeld bij het lezen uit een kanaal zonder gegevens of bij een systeemaanroep), ontkoppelt M zich van P, en P wordt beschikbaar om een andere goroutine uit te voeren. De geblokkeerde goroutine wordt in afwachting gezet. Wanneer de blokkering wordt opgeheven, wordt de goroutine weer runnable en terug in de wachtrij geplaatst.
  6. Als M wordt geblokkeerd in een systeemaanroep, houdt het P niet vast. Er kan een nieuwe M worden gemaakt of een bestaande worden gebruikt, zodat P andere goroutines kan blijven uitvoeren.

Deze aanpak maakt efficiënt gebruik van de processorbronnen mogelijk en schaalt gemakkelijk parallelle taken, terwijl de complexiteit van het beheer van OS-threads voor de ontwikkelaar wordt verborgen.

// Voorbeeld van het maken van een goroutine
func myFunc() {
	// Goroutine-code
}

func main() {
	go myFunc() // Start van de goroutine
	// Het hoofdprogramma blijft parallel doorgaan
}