Sobes.tech
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 (հաճախ՝ պրոցեսորի միջուկների քանակը):

Ինչպես է աշխատում:

  1. Go-ի ռանթայմի (runtime) մասն է՝ պլանավորիչը, տեղադրում է նոր goroutine-ներ P-ի գլոբալ կամ տեղական հերթերում:
  2. P-ի հետ կապված M-ը վերցնում է goroutine-ներ P-ի հերթից և կատարում է դրանք:
  3. Երբ goroutine-ները բլոկավորվում են (օրինակ՝ I/O սպասելիս կամ mutex-ով).:
    • M-ը առանձնանում է ընթացիկ P-ից:
    • Պլանավորիչը փորձում է գտնել այլ M, որը կզբաղեցնի այդ P-ը, կամ ստեղծում է նոր:
    • Բլոկավորված goroutine-ը տեղադրվում է հատուկ հերթում:
    • Երբ բլոկավորումը վերացվում է, goroutine-ը կրկին դառնում է runnable և վերադառնում P-ի հերթ:
  4. Երբ 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) // Գործողությունների ավարտին սպասում
}