Планировщик Go работает по модели GMP: G (goroutine), M (OS-thread), P (processor, GOMAXPROCS штук). Каждый P имеет локальную run-очередь на 256 горутин + есть глобальная очередь.
Алгоритм: P берёт горутину из своей очереди. Если пуста — work stealing: крадёт половину из очереди другого P или берёт из глобальной. Это обеспечивает балансировку нагрузки.
Переключение происходит при: вызовах функций (preemption points), операциях с каналами, системных вызовах, runtime.Gosched(), аллокациях. С Go 1.14 — асинхронное вытеснение через SIGURG для tight loops.