Middle+
Պատմեք մրցակցային կառավարման մոդել (GMP) մասին Go լեզվում։
sobes.tech AI
Պատասխան AI-ից
GMP-ը Go-ում goroutine-ների կատարման պլանավորման մոդել է, որտեղ:
- G (Goroutine): Թեթև քարշակ, համակարգային թելերի վերածնունդ։
- M (Machine): Օպերացիոն համակարգի թել։ Կարող է կատարել մեկ կամ մի քանի goroutine-ների կոդը:
- P (Processor): Լոգիկ պրոցեսոր, որը ներկայացնում է կոնտեքստ goroutine-ների կատարման համար։ Յուրաքանչյուր P-ին վերապահված է M, և P-ն պարունակում է տեղական հերթ՝ runnable goroutine-ների համար։ Բնական P-ների քանակը՝
$GOMAXPROCS(հաճախ՝ պրոցեսորի միջուկների քանակը):
Ինչպես է աշխատում:
- Go-ի ռանթայմի (runtime) մասն է՝ պլանավորիչը, տեղադրում է նոր goroutine-ներ P-ի գլոբալ կամ տեղական հերթերում:
- P-ի հետ կապված M-ը վերցնում է goroutine-ներ P-ի հերթից և կատարում է դրանք:
- Երբ goroutine-ները բլոկավորվում են (օրինակ՝ I/O սպասելիս կամ mutex-ով).:
- M-ը առանձնանում է ընթացիկ P-ից:
- Պլանավորիչը փորձում է գտնել այլ M, որը կզբաղեցնի այդ P-ը, կամ ստեղծում է նոր:
- Բլոկավորված goroutine-ը տեղադրվում է հատուկ հերթում:
- Երբ բլոկավորումը վերացվում է, goroutine-ը կրկին դառնում է runnable և վերադառնում P-ի հերթ:
- Երբ goroutine-ը սպառում է իր ժամանակային քվանտը կամ բացահայտ փոխանցում է կառավարումը (քչից), պլանավորիչը կարող է փոխել M-ը այլ goroutine-ի վրա նույն P-ում:
Առավելություններ՝
- Սիստեմային թելերի արդյունավետ օգտագործում:
- Կոնտեքստային փոփոխությունների ծախսերի նվազեցում՝ համեմատած բնիկ համակարգային թելերի:
- Բեռի հավասարակշռություն 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) // Գործողությունների ավարտին սպասում
}