Camada Zero · 06 · Goroutines & o Scheduler M:N

Você escreve `go func()` e acha que criou uma thread. Não criou. O runtime do Go multiplexa milhares de goroutines em um punhado de threads do SO. Spawna 1000 aqui embaixo e olha o número de threads quase não se mexer.
Bloqueadas em syscall (cada uma segura uma M dedicada)
0Goroutines (G)
4P (GOMAXPROCS)
4Threads do SO (M)
0Trocas de contexto
rodando (na M) na fila do P bloqueada em syscall
G = goroutine, P = processador lógico (quantos rodam em paralelo), M = thread do SO. O scheduler do Go encaixa muitos G em poucos M, com uma fila por P e work stealing: um P ocioso rouba metade da fila do P mais cheio. Por isso 1000 goroutines não viram 1000 threads.
GoroutineThread do SO
Stack inicial~2 KB (cresce)~1 MB (fixa)
Criaçãobaratacara (syscall)
Agendamentouser spacekernel
Quantidadecentenas de milharesmilhares

Em Go

func main() {
    runtime.GOMAXPROCS(4) // nº de P (paralelismo)
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func(id int) { // 1000 goroutines, ~2KB cada
            defer wg.Done()
            work(id)
        }(i)
    }
    wg.Wait() // espera todas terminarem
}

🧠 Desafio — Goroutines & Scheduler

Mexe no visualizador (spawna goroutines, muda o GOMAXPROCS, bloqueia em syscall) antes de responder. As duas últimas são de reflexão: escreve a sua e só então revela o modelo.