Sobes.tech
Middle+

Ispričajte o obrascu upravljanja konkurentnošću (GMP) u jeziku Go.

sobes.tech АИ

Одговор од АИ

GMP је модел планирања извршавања goroutine у Go-у, где:

  • G (Goroutine): Лагани ток извршавања, апстракција над системским нитима.
  • M (Machine): Нит оперативног система. Може извршавати код једне или више goroutine-а.
  • P (Processor): Логички процесор који представља контекст за извршавање goroutine-а. Сваком P је додељен M, а P садржи локалну реду за извршне goroutine-е. Број P по подразумеванњу је $GOMAXPROCS (обично број језгара процесора).

Како функционише:

  1. Планер (дело runtime-а Go) поставља нове goroutine-е у глобалне или локалне редове P.
  2. M, повезан са P, узима goroutine из реда P и извршава је.
  3. Када goroutine блокира (нпр. при чекању I/O или на mutex-у):
    • M се одваја од тренутног P.
    • Планер покушава да пронађе други M који ће заузети тај P, или креира нови.
    • Блокирана goroutine се ставља у специјалну реду.
    • Када се блокирање уклони, goroutine поново постаје runnable и враћа се у ред P.
  4. Када 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) // Чекамо да се goroutine-ји заврше
}