Sobes.tech
Junior — Middle

Come si comporta un programma in Go quando GOMAXPROCS è impostato su 1 e viene avviata una goroutine con un ciclo infinito, se nel frattempo si tenta di eseguire un'altra parte del codice?

sobes.tech AI

Risposta dell'AI

Impostando GOMAXPROCS=1 in un programma Go, si limita il numero di thread di sistema che possono essere eseguiti contemporaneamente a uno. Se si avvia una goroutine con un ciclo infinito senza chiamare funzioni che consentono allo scheduler di cambiare contesto (ad esempio, time.Sleep, runtime.Gosched), questa goroutine occuperà l'unico thread e bloccherà l'esecuzione di altre goroutine.

Di conseguenza, un'altra parte del codice eseguita in altre goroutine non potrà essere eseguita in parallelo e attenderà che il ciclo infinito ceda il controllo. Ciò è dovuto al fatto che lo scheduler di goroutine di Go, a livello utente, cambia l'esecuzione tra goroutine, ma con GOMAXPROCS=1 c'è solo un thread del sistema operativo, e se la goroutine non permette allo scheduler di cambiare, le altre si bloccano.

Esempio:

package main

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

func main() {
	runtime.GOMAXPROCS(1)

	go func() {
		for {
			// ciclo infinito senza yield
		}
	}()

	time.Sleep(time.Second) // diamo tempo alla goroutine di avviarsi

	fmt.Println("Un'altra parte del codice") // potrebbe non essere mai eseguita
}

Per evitare blocchi, nel ciclo infinito bisogna inserire chiamate che consentano allo scheduler di cambiare contesto, come runtime.Gosched() o time.Sleep.