Middle+
Parla del pattern di gestione della concorrenza (GMP) nel linguaggio Go.
sobes.tech AI
Risposta dell'AI
GMP è un modello di pianificazione dell'esecuzione delle goroutine in Go, dove:
- G (Goroutine): Un thread leggero di esecuzione, un'astrazione sopra i thread di sistema.
- M (Machine): Un thread del sistema operativo. Può eseguire il codice di una o più goroutine.
- P (Processor): Un processore logico, che rappresenta un contesto per l'esecuzione delle goroutine. A ogni P è assegnato un M, e P contiene una coda locale di goroutine in stato runnable. Il numero di P di default è
$GOMAXPROCS(solitamente il numero di core del processore).
Funziona così:
- Lo scheduler (parte del runtime di Go) mette le nuove goroutine nelle code globali o locali di P.
- Un M, associato a un P, prende una goroutine dalla coda di P e la esegue.
- Quando una goroutine si blocca (ad esempio, in attesa di I/O o su un mutex):
- M si dissocia dal P corrente.
- Lo scheduler cerca un altro M per occupare quel P, o ne crea uno nuovo.
- La goroutine bloccata viene messa in una coda speciale.
- Quando il blocco viene rimosso, la goroutine torna in stato runnable e ritorna nella coda di P.
- Quando la goroutine esaurisce il suo quantum di tempo o cede esplicitamente il controllo (raramente), lo scheduler può cambiare M con un'altra goroutine nello stesso P.
Vantaggi di questo approccio:
- Uso efficiente dei thread di sistema M.
- Riduzione dei costi di cambio di contesto rispetto ai thread nativi del sistema operativo.
- Bilanciamento del carico tra P tramite il meccanismo di "work stealing" (M può rubare una goroutine dalla coda di un altro P).
Esempio di creazione di una goroutine:
// main.go
package main
import (
"fmt"
"time"
)
func worker(id int) {
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second) // Illustrazione di blocco/occupazione
fmt.Printf("Worker %d finished\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
go worker(i) // Creiamo una nuova goroutine
}
time.Sleep(time.Second * 2) // Aspettiamo che le goroutine finiscano
}