Sobes.tech
Junior — Middle

Hogyan viselkedik egy Go nyelvű program, amikor a GOMAXPROCS = 1 beállítás mellett egy végtelen ciklussal rendelkező goroutine indítunk, és közben megpróbálunk egy másik kódrészt futtatni?

sobes.tech MI

Válasz az MI-től

Amikor GOMAXPROCS=1 van beállítva egy Go programban, akkor a rendszer szálak száma, amelyek egyidejűleg futtathatók, egyre korlátozódik. Ha egy végtelen ciklussal rendelkező gorutint indítunk anélkül, hogy olyan függvényeket hívnánk meg, amelyek lehetővé teszik a ütemező számára a kontextus váltását (például time.Sleep, runtime.Gosched), akkor ez a gorutin foglalja az egyetlen szálat, és blokkolja más gorutinok végrehajtását.

Ennek eredményeként egy másik kódrészlet, amely más gorutinokban fut, nem fog párhuzamosan végrehajtódni, és várni fog arra, hogy a végtelen ciklus átadja az irányítást. Ez abból adódik, hogy a Go gorutinhozáró ütemezője felhasználói szinten váltogatja a végrehajtást a gorutinok között, de GOMAXPROCS=1 esetén csak egy OS szál van, és ha a gorutin nem engedi az ütemezőnek a váltást, a többi blokkolva lesz.

Példa:

package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	runtime.GOMAXPROCS(1)

	go func() {
		for {
			// végtelen ciklus yield nélkül
		}
	}()

	time.Sleep(time.Second) // időt adunk a gorutinnak a starthoz

	fmt.Println("Másik kódrész") // lehet, hogy soha nem fog végrehajtódni
}

A blokkolások elkerülése érdekében a végtelen ciklusban olyan hívásokat kell beilleszteni, amelyek lehetővé teszik az ütemező számára a váltást, például runtime.Gosched() vagy time.Sleep.