Middle+
Povězte o vzoru řízení konkurence (GMP) v jazyce Go.
sobes.tech AI
Odpověď od AI
GMP je model plánování provádění gorutin v Go, kde:
- G (Goroutine): Lehký vlákno provádění, abstrakce nad systémovými vlákny.
- M (Machine): Vlákno operačního systému. Může vykonávat kód jedné nebo více gorutin.
- P (Processor): Logický procesor, který představuje kontext pro vykonávání gorutin. Každému P je přiřazeno M a P obsahuje místní frontu běžících gorutin. Počet P je ve výchozím nastavení
$GOMAXPROCS(obvykle počet jader procesoru).
Jak to funguje:
- Plánovač (část runtime Go) umisťuje nové gorutiny do globálních nebo lokálních front P.
- M, spojené s P, vezme gorutinu z fronty P a vykoná ji.
- Když gorutina zablokuje (například při čekání na I/O nebo na mutexu):
- M se odpojí od aktuálního P.
- Plánovač se pokusí najít jiný M, který obsadí P, nebo vytvoří nový.
- Zablokovaná gorutina je umístěna do speciální fronty.
- Když je blokování odstraněno, gorutina se znovu stává runnable a vrací se do fronty P.
- Když gorutina vyčerpá svůj časový kvantum nebo explicitně předá řízení (zřídka), může plánovač změnit M na jinou gorutinu ve stejném P.
Výhody:
- Efektivní využití systémových vláken M.
- Snížení nákladů na přepínání kontextu ve srovnání s nativními systémovými vlákny.
- Vyrovnávání zátěže mezi P pomocí mechanismu "work stealing" (M může ukrást gorutinu z fronty jiného P).
Příklad vytvoření gorutiny:
// main.go
package main
import (
"fmt"
"time"
)
func worker(id int) {
fmt.Printf("Pracovník %d začíná\n", id)
time.Sleep(time.Second) // Ilustrace blokování/zátěže
fmt.Printf("Pracovník %d končí\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
go worker(i) // Vytvoření nové gorutiny
}
time.Sleep(time.Second * 2) // Čekání na dokončení gorutin
}