Sobes.tech
Middle

Mi az a futási idő (runtime) és hogyan működik a ütemező (scheduler)?

sobes.tech MI

Válasz az MI-től

A Go futásideje (runtime) a környezet, amelyben a Go programok futnak. Magába foglalja:

  • Memóriakezelés: A szemétgyűjtő (garbage collector) automatikusan kezeli a memória kiosztását és felszabadítását.
  • Ütemező (scheduler): Kezeli a goroutine-ok végrehajtását az operációs rendszer szálain.
  • Rendszerhívások: Interfészt biztosít a rendszerrel való kommunikációhoz.
  • Szinkronizációs primitívek: Csatornák, mutexek és más mechanizmusok a goroutine-ok koordinálására.

A Go ütemezője az M:N modellt valósítja meg (sok goroutine sok OS-szálon). Fő komponensei:

  • G (Goroutine): Egy könnyű végrehajtási szál, alapvetően egy függvény absztrakciója.
  • M (Machine): Egy operációs rendszer szál, amelyen a Go programok futnak.
  • P (Processor): Egy logikai processzor, amelyhez egy OS-szál kapcsolódik. Tartalmaz egy helyi runnable sorozatot goroutine-ok számára.

Az ütemező működési elve:

  1. Goroutine-ok (G) létrejönnek és hozzáadódnak egy globális vagy helyi runnable sorhoz.
  2. Az OS-szálak (M) logikai processzorokhoz (P) kapcsolódnak. Az alapértelmezett P száma megegyezik a CPU magok számával (GOMAXPROCS).
  3. P kiválaszt egy goroutine-t a helyi sorából. Ha a helyi sor üres, P megpróbálja "ellopni" (steal) goroutine-okat más P-k vagy a globális sorból.
  4. M végrehajtja a goroutine-t.
  5. Amikor egy goroutine blokkolódik (pl. csatornából olvasás adat nélkül vagy rendszerhívás során), M leválik P-ről, és P elérhetővé válik más goroutine-ok futtatására. A blokkolt goroutine várakozó állapotba kerül. Amikor a blokkolás megszűnik, a goroutine újra runnable lesz, és visszakerül a sorba.
  6. Ha M rendszerhívásban blokkol, nem tartja P-t. Létrehozható egy új M vagy használható egy meglévő, hogy P folytathassa más goroutine-ok futtatását.

Ez a megközelítés hatékonyan használja ki a processzor erőforrásait, és könnyen skálázható párhuzamos feladatok esetén, miközben elrejti az OS-szálak kezelésének összetettségét a fejlesztő elől.

// Goroutine létrehozásának példája
func myFunc() {
	// Goroutine kódja
}

func main() {
	go myFunc() // Goroutine indítása
	// A fő program párhuzamosan folytatódik
}