Sobes.tech
Middle

Co je to doba běhu (runtime) a jak funguje plánovač (scheduler)?

sobes.tech AI

Odpověď od AI

Doba běhu (runtime) v Go je prostředí, ve kterém jsou spouštěny programy v Go. Zahrnuje:

  • Správu paměti: Sběrač odpadu (garbage collector) automaticky spravuje alokaci a uvolnění paměti.
  • Plánovač (scheduler): Řídí vykonávání gorutin na vláknech operačního systému.
  • Systémové volání: Poskytuje rozhraní pro interakci s operačním systémem.
  • Primitivy synchronizace: Kanály, mutexy a další mechanismy pro koordinaci gorutin.

Plánovač v Go implementuje model M:N (mnoho gorutin na mnoho vláken OS). Jeho hlavní komponenty:

  • G (Goroutine): Lehký vlákno, v podstatě abstrakce nad funkcí.
  • M (Machine): Vlákno operačního systému, na kterém běží programy v Go.
  • P (Processor): Logický procesor spojený s vláknem OS. Uchovává lokální frontu runnable gorutin.

Princip fungování plánovače:

  1. Gorutiny (G) jsou vytvářeny a přidávány do globální nebo lokální fronty runnable.
  2. Vlákna OS (M) jsou spojena s logickými procesory (P). Počet P je ve výchozím nastavení roven počtu jader CPU (GOMAXPROCS).
  3. P bere gorutinu ze své lokální fronty. Pokud je lokální fronta prázdná, P se pokusí "ukrást" (steal) gorutiny z fronty jiného P nebo z globální fronty.
  4. M vykonává gorutinu.
  5. Když gorutina zablokuje (například při čtení z kanálu bez dat nebo při systémovém volání), M se odpojí od P a P se stává dostupným pro vykonávání jiné gorutiny. Zablokovaná gorutina je nastavena do čekacího stavu. Když je blokování odstraněno, gorutina se opět stává runnable a je vrácena do fronty.
  6. Pokud se M zablokuje ve systémovém volání, nezadržuje P. Může být vytvořeno nové M nebo může být použito existující, aby P mohl pokračovat v vykonávání dalších gorutin.

Tento přístup umožňuje efektivní využití procesorových zdrojů a snadné škálování paralelních úloh, zatímco složitost správy vláken OS je skryta před vývojářem.

// Příklad vytvoření gorutiny
func myFunc() {
	// Kód gorutiny
}

func main() {
	go myFunc() // Spuštění gorutiny
	// Hlavní program pokračuje ve vykonávání paralelně
}