Ответ
Горутина уступает место другой в следующих случаях:
- При вызове runtime.Gosched() - явное указание планировщику переключиться
go func() {
runtime.Gosched() // уступаем место
}()
-
При блокирующих операциях:
- Каналы (отправка/получение)
- Системные вызовы (файловый ввод-вывод, сетевые операции)
- Вызовы time.Sleep()
- Работа с sync.Mutex и другими примитивами синхронизации
-
При достижении кванта времени (обычно ~10мс) - автоматическое переключение планировщиком
-
При вызове функций из runtime - например, сборка мусора может привести к переключению
Горутины кооперативны - они не вытесняются произвольно, а только в указанных точках. Это отличается от потоков ОС, которые могут быть вытеснены в любой момент.