Middle+
Povedzte o vzorec riadenia konkurencie (GMP) v jazyku Go.
sobes.tech AI
Odpoveď od AI
GMP je model plánovania vykonávania goroutines v Go, kde:
- G (Goroutine): Ľahký vlákno na vykonávanie, abstrakcia nad systémovými vláknami.
- M (Machine): Vlákno operačného systému. Môže vykonávať kód jednej alebo viacerých goroutines.
- P (Processor): Logický procesor, ktorý predstavuje kontext na vykonávanie goroutines. Každému P je pridelené M a P obsahuje lokálnu frontu runnable goroutines. Počet P je predvolený na
$GOMAXPROCS(zvyčajne počet jadier procesora).
Ako to funguje:
- Plánovač (časť runtime Go) umiestňuje nové goroutines do globálnych alebo lokálnych front P.
- M, spojené s P, vezme goroutine z fronty P a vykoná ju.
- Keď goroutine zablokuje (napríklad pri čakaní na I/O alebo na mutexe):
- M sa odpojí od aktuálneho P.
- Plánovač sa pokúsi nájsť iné M, ktoré obsadí P, alebo vytvorí nové.
- Zablokovaná goroutine sa umiestni do špeciálnej fronty.
- Keď sa blokovanie odstráni, goroutine sa stáva znova runnable a vráti sa do fronty P.
- Keď goroutine vyčerpá svoj kvant času alebo explicitne odovzdá kontrolu (zriedka), plánovač môže zmeniť M na inú goroutine v tom istom P.
Výhody:
- Efektívne využívanie systémových vlákien M.
- Zníženie nákladov na prepínanie kontextu v porovnaní s natívnymi systémovými vláknami.
- Vyvažovanie záťaže medzi P pomocou mechanizmu "work stealing" (M môže ukradnúť goroutine z fronty iného P).
Príklad vytvorenia goroutine:
// main.go
package main
import (
"fmt"
"time"
)
func worker(id int) {
fmt.Printf("Pracovník %d začína\n", id)
time.Sleep(time.Second) // Ilustrácia blokovania/záťaže
fmt.Printf("Pracovník %d končí\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
go worker(i) // Vytvorenie novej goroutine
}
time.Sleep(time.Second * 2) // Čakanie na ukončenie goroutine
}