Sobes.tech
Junior — Middle

Jak se chová program v jazyce Go při nastavení GOMAXPROCS = 1 a spuštění gorutiny s nekonečným cyklem, pokud se při tom pokusíte spustit jinou část kódu?

sobes.tech AI

Odpověď od AI

Nastavíte-li GOMAXPROCS=1 v programu Go, omezí se počet systémových vláken, která mohou být současně spuštěna, na jedno. Pokud spustíte gorutinu s nekonečným cyklem bez volání funkcí, které umožňují plánovači přepínat kontext (například time.Sleep, runtime.Gosched), tato gorutina obsadí jedinou vlákno a zablokuje provádění ostatních gorutin.

Výsledkem je, že jiná část kódu spuštěná v jiných gorutinách se nemůže spouštět paralelně a bude čekat, dokud nekonečný cyklus nepředá řízení. To je způsobeno tím, že plánovač gorutin v Go na úrovni uživatele přepíná provádění mezi gorutinami, ale při GOMAXPROCS=1 je k dispozici pouze jedno vlákno OS, a pokud gorutina neumožní plánovači přepnout, ostatní jsou zablokované.

Příklad:

package main

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

func main() {
	runtime.GOMAXPROCS(1)

	go func() {
		for {
			// nekonečný cyklus bez yield
		}
	}()

	time.Sleep(time.Second) // dáme čas gorutině na spuštění

	fmt.Println("Jiná část kódu") // může se nikdy nevykonat
}

Abychom se vyhnuli blokování, je třeba v nekonečném cyklu vkládat volání, která umožní plánovači přepnout kontext, například runtime.Gosched() nebo time.Sleep.