Middle+
Vorbește despre modelul de gestionare a concurenței (GMP) în limbajul Go.
sobes.tech AI
Răspuns de la AI
GMP este un model de planificare a executării goroutine-urilor în Go, unde:
- G (Goroutine): Un fir de execuție ușor, o abstracție peste firele de sistem.
- M (Machine): Un fir al sistemului de operare. Poate executa codul uneia sau mai multor goroutine-uri.
- P (Processor): Un procesor logic, care reprezintă un context pentru executarea goroutine-urilor. Fiecărui P îi este atribuit un M, iar P conține o coadă locală de goroutine-uri runnable. Numărul de P implicit este
$GOMAXPROCS(de obicei numărul de nuclee ale procesorului).
Funcționare:
- Planificatorul (parte a runtime-ului Go) plasează noile goroutine-uri în cozi globale sau locale ale P.
- Un M, asociat cu un P, preia o goroutine din coada P și o execută.
- Când o goroutine se blochează (de exemplu, așteptând I/O sau pe un mutex):
- M se detașează de P-ul curent.
- Planificatorul încearcă să găsească alt M pentru a ocupa acel P sau creează unul nou.
- Goroutine-ul blocat este plasat într-o coadă specială.
- Când blocarea este ridicată, goroutine-ul devine din nou runnable și revine în coada P.
- Când goroutine-ul își consumă cuantumul de timp sau cedează explicit controlul (rar), planificatorul poate schimba M-ul cu altă goroutine din același P.
Avantaje:
- Utilizare eficientă a firelor M ale sistemului.
- Reducerea costurilor de schimbare a contextului comparativ cu firele native ale sistemului de operare.
- Echilibrare a încărcării între P prin mecanismul de "work stealing" (M poate fura o goroutine din coada altui P).
Exemplu de creare a unei goroutine:
// main.go
package main
import (
"fmt"
"time"
)
func worker(id int) {
fmt.Printf("Lucrător %d începe\n", id)
time.Sleep(time.Second) // Ilustrație de blocare/ocupare
fmt.Printf("Lucrător %d termină\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
go worker(i) // Creăm o goroutine nouă
}
time.Sleep(time.Second * 2) // Așteptăm finalizarea goroutine-urilor
}