Sobes.tech
Middle

Čo je čas behu (runtime) a ako funguje plánovač (scheduler)?

sobes.tech AI

Odpoveď od AI

Čas behu (runtime) v Go je prostredie, v ktorom sa vykonávajú Go programy. Zahŕňa:

  • Správa pamäte: Zberač odpadkov (garbage collector) automaticky spravuje alokáciu a uvoľňovanie pamäte.
  • Plánovač (scheduler): Riadi vykonávanie gorútín na vlákna operačného systému.
  • Systémové volania: Poskytuje rozhranie na interakciu s operačným systémom.
  • Primitívy synchronizácie: Kanály, muteksy a ďalšie mechanizmy na koordináciu gorútín.

Plánovač Go implementuje model M:N (množstvo gorútín na množstvo vlákien OS). Jeho hlavné komponenty:

  • G (Goroutine): Ľahký vlákno vykonávania, v podstate abstrakcia nad funkciou.
  • M (Machine): Vlákno operačného systému, na ktorom sa vykonávajú Go programy.
  • P (Processor): Logický procesor spojený s vláknom OS. Uchováva lokálnu frontu runnable gorútín.

Princíp práce plánovača:

  1. Gorutiny (G) sa vytvárajú a pridávajú do globálnej alebo lokálnej fronty runnable.
  2. Vlákna OS (M) sú asociované s logickými procesormi (P). Počet P je štandardne rovný počtu jadier CPU (GOMAXPROCS).
  3. P si berie gorutinu zo svojej lokálnej fronty. Ak je lokálna fronta prázdna, P sa pokúsi "ukradnúť" (steal) gorutiny z fronty iného P alebo z globálnej fronty.
  4. M vykonáva gorutinu.
  5. Keď sa gorutina zablokuje (napríklad pri čítaní z kanála bez dát alebo pri systémovom volaní), M sa odpojí od P a P sa stáva dostupným na vykonávanie inej gorutiny. Zablokovaná gorutina sa nastaví do čakacieho režimu. Keď sa blokovanie odstráni, gorutina sa opäť stáva runnable a vloží sa späť do fronty.
  6. Ak sa M zablokuje v systémovom volaní, neudržiava P. Môže byť vytvorený nový M alebo použitý existujúci, aby P mohol pokračovať vo vykonávaní iných gorútín.

Tento prístup umožňuje efektívne využívanie zdrojov procesora a ľahko škáluje paralelné úlohy, skrývajúc zložitosť správy vlákien OS pred vývojárom.

// Príklad vytvorenia gorutiny
func myFunc() {
	// Kód gorutiny
}

func main() {
	go myFunc() // Spustenie gorutiny
	// Hlavný program pokračuje vo vykonávaní paralelne
}