Sobes.tech
Middle

Ce este timpul de execuție (runtime) și cum funcționează planificatorul (scheduler)?

sobes.tech AI

Răspuns de la AI

Timpul de execuție (runtime) în Go reprezintă mediul în care rulează programele Go. Acesta include:

  • Gestionarea memoriei: Colectorul de gunoi (garbage collector) gestionează automat alocarea și eliberarea memoriei.
  • Planificator (scheduler): Gestionează executarea goroutine-urilor pe firele de execuție ale sistemului de operare.
  • Apeluri de sistem: Oferă o interfață pentru interacțiunea cu sistemul de operare.
  • Primitive de sincronizare: Canale, mutexuri și alte mecanisme pentru coordonarea goroutine-urilor.

Planificatorul Go implementează modelul M:N (mai multe goroutine pe mai multe fire de sistem de operare). Componentele principale:

  • G (Goroutine): Un fir de execuție ușor, în esență o abstracție peste o funcție.
  • M (Machine): Un fir de sistem de operare pe care rulează programele Go.
  • P (Processor): Un procesor logic asociat cu un fir de sistem de operare. P păstrează o coadă locală runnable de goroutine-uri.

Principiul de funcționare al planificatorului:

  1. Goroutine-urile (G) sunt create și adăugate într-o coadă globală sau locală runnable.
  2. Firurile de sistem de operare (M) sunt asociate cu procesoare logice (P). Numărul de P implicit este egal cu numărul de nuclee CPU (GOMAXPROCS).
  3. P preia o goroutine din coada sa locală. Dacă coada locală este goală, P încearcă să "fure" (steal) goroutine-uri din coada altui P sau din coada globală.
  4. M execută goroutine-ul.
  5. Când o goroutine se blochează (de exemplu, la citirea dintr-un canal fără date sau la efectuarea unui apel de sistem), M se deconectează de la P, iar P devine disponibil pentru executarea altei goroutine-uri. Goroutine-ul blocat este pus în așteptare. Când blocarea este eliminată, goroutine-ul devine din nou runnable și este pus înapoi în coadă.
  6. Dacă M se blochează într-un apel de sistem, nu menține P. Se poate crea un M nou sau se poate folosi unul existent, astfel încât P să poată continua executarea altor goroutine-uri.

Această abordare permite utilizarea eficientă a resurselor procesorului și scalarea ușoară a sarcinilor paralele, ascunzând complexitatea gestionării firelor de sistem ale sistemului de operare pentru dezvoltator.

// Exemplu de creare a unei goroutine
func myFunc() {
	// Codul goroutine-ului
}

func main() {
	go myFunc() // Pornirea goroutine-ului
	// Programul principal continuă execuția în paralel
}