Sobes.tech
Junior — Middle

Kaip elgiasi programa Go kalboje, kai GOMAXPROCS nustatyta kaip 1 ir pradeda gorutina su begaline ciklu, jei tuo pačiu metu bandote vykdyti kitą kodo dalį?

sobes.tech AI

Atsakymas iš AI

Nustatę GOMAXPROCS=1 Go programoje, vienu metu veikiančių sisteminių sriegių skaičius yra apribotas iki vieno. Jei paleidžiate gorutina su begaline ciklu be funkcijų, leidžiančių planuotojui keisti kontekstą (pvz., time.Sleep, runtime.Gosched), ši gorutina užims vienintelį sriegi ir blokuos kitų gorutinos vykdymą.

Dėl to, kita kodo dalis, vykdoma kitose gorutinose, negalės vykdyti paraleliai ir lauks, kol begalinė ciklas perduos valdymą. Tai susiję su tuo, kad Go gorutinos planuotojas vartotojo lygyje keičia vykdymą tarp gorutinų, tačiau su GOMAXPROCS=1 yra tik viena OS sritis, ir jei gorutina neleidžia planuotojui keisti, kitos gorutinos blokuojamos.

Pavyzdys:

package main

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

func main() {
	runtime.GOMAXPROCS(1)

	go func() {
		for {
			// begalinė ciklas be yield
		}
	}()

	time.Sleep(time.Second) // suteikiame laiko gorutina pradėti

	fmt.Println("Kitos kodo dalis") // gali niekada neįvykti
}

Kad išvengtumėte užblokavimo, begalinėje cikle reikia įterpti iškvietimus, leidžiančius planuotojui keisti kontekstą, pvz., runtime.Gosched() arba time.Sleep.