Middle+
Разкажете за модела за управление на конкуренцията (GMP) в езика Go.
sobes.tech AI
Отговор от AI
GMP е модел за планиране на изпълнението на goroutines в Go, където:
- G (Goroutine): Лека нишка за изпълнение, абстракция над системните нишки.
- M (Machine): Нишка на операционната система. Може да изпълнява кода на една или повече goroutines.
- P (Processor): Логически процесор, който представлява контекст за изпълнение на goroutines. На всеки P е назначен M, и P съдържа локална опашка с runnable goroutines. Броят на P по подразбиране е
$GOMAXPROCS(обикновено броят на ядрата на процесора).
Как работи:
- Планировчикът (част от runtime на Go) поставя нови goroutines в глобалните или локалните опашки на P.
- M, свързан с P, взема goroutine от опашката на P и я изпълнява.
- Когато goroutine блокира (например, при изчакване на I/O или mutex):
- M се отделя от текущия P.
- Планировчикът се опитва да намери друг M, който да заеме този P, или създава нов.
- Блокираната goroutine се поставя в специална опашка.
- Когато блокирането бъде премахнато, goroutine отново става runnable и се връща в опашката на P.
- Когато goroutine изчерпи квант от време или явно предаде управлението (рядко), планировчикът може да превключи M към друга goroutine в същия P.
Предимства:
- Ефективно използване на системните нишки M.
- Намаляване на разходите за превключване на контекста в сравнение с нативните системни нишки.
- Балансиране на натоварването между P чрез механизма "work stealing" (M може да открадне goroutine от опашката на друг P).
Пример за създаване на goroutine:
// main.go
package main
import (
"fmt"
"time"
)
func worker(id int) {
fmt.Printf("Работник %d започва\n", id)
time.Sleep(time.Second) // Иллюстрация на блокиране/заетост
fmt.Printf("Работник %d завършва\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
go worker(i) // Създаване на нова goroutine
}
time.Sleep(time.Second * 2) // Изчакване за завършване на goroutines
}