Sobes.tech
Junior — Middle

Kuidas käitub programm Go keeles, kui GOMAXPROCS on seatud väärtusele 1 ja käivitatakse goroutine lõpmatu tsükliga, kui samal ajal püüate käivitada teist koodi osa?

sobes.tech AI

Vastus AI-lt

Kui määrate GOMAXPROCS=1 Go programmis, piirab see samaaegselt töötavate süsteemilõimede arvu ühega. Kui käivitada goroutine lõpmatu tsükliga ilma funktsioonide kutsumiseta, mis võimaldavad plaanijal konteksti vahetada (näiteks time.Sleep, runtime.Gosched), siis see goroutine hõivab ainsana selle ühe lõime ja blokeerib teiste goroutine'ide täitmise.

Tulemuseks on, et teine koodiosa, mis töötab teistes goroutine'ides, ei saa töötada paralleelselt ja ootab, kuni lõpmatu tsükkel annab juhtimise üle. See on seotud sellega, et Go goroutine-plaanija kasutaja tasandil vahetab täitmist goroutine'ide vahel, kuid GOMAXPROCS=1 puhul on ainult üks OS lõim, ja kui goroutine ei võimalda plaanijal vahetada, blokeeritakse teised.

Näide:

package main

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

func main() {
	runtime.GOMAXPROCS(1)

	go func() {
		for {
			// lõpmatu tsükkel ilma yieldita
		}
	}()

	time.Sleep(time.Second) // anname goroutine'ile aega käivituda

	fmt.Println("Teine koodiosa") // võib kunagi mitte täita
}

Blokeeringute vältimiseks tuleb lõpmatus tsüklis sisestada kutsed, mis võimaldavad plaanijal vahetada konteksti, näiteks runtime.Gosched() või time.Sleep.