Sobes.tech
Junior — Middle

Como se comporta um programa na linguagem Go quando GOMAXPROCS é definido como 1 e uma goroutine com um ciclo infinito é iniciada, se ao mesmo tempo tentar executar outra parte do código?

sobes.tech IA

Resposta da IA

Ao definir GOMAXPROCS=1 num programa Go, o número de threads do sistema que podem estar a trabalhar simultaneamente é limitado a um. Se iniciar uma goroutine com um ciclo infinito sem chamar funções que permitam ao escalonador trocar de contexto (por exemplo, time.Sleep, runtime.Gosched), essa goroutine ocupará o único thread e bloqueará a execução de outras goroutines.

Como resultado, outra parte do código executada em outras goroutines não poderá ser executada em paralelo e aguardará que o ciclo infinito ceda o controlo. Isto deve-se ao fato de que o escalonador de goroutines do Go, ao nível de utilizador, troca a execução entre goroutines, mas com GOMAXPROCS=1, há apenas um thread do sistema operativo, e se a goroutine não permitir que o escalonador troque, as demais ficam bloqueadas.

Exemplo:

package main

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

func main() {
	runtime.GOMAXPROCS(1)

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

	time.Sleep(time.Second) // damos tempo à goroutine para iniciar

	fmt.Println("Outra parte do código") // pode nunca ser executada
}

Para evitar bloqueios, no ciclo infinito deve-se inserir chamadas que permitam ao escalonador trocar de contexto, como runtime.Gosched() ou time.Sleep.