Sobes.tech
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:

  1. Plánovač (část runtime Go) umisťuje nové gorutiny do globálních nebo lokálních front P.
  2. M, spojené s P, vezme gorutinu z fronty P a vykoná ji.
  3. 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.
  4. 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
}