Ответ
Планировщик (scheduler) в Go управляет горутинами (goroutines) и их выполнением на потоках ОС (threads). Он использует M:N модель, где M горутин распределяются по N потокам ОС.
Основные компоненты:
- G (Goroutine) – легковесный поток, управляемый рантаймом Go.
- M (Machine) – поток ОС, выполняющий горутины.
- P (Processor) – контекст планировщика, связывает M и G.
Как работает:
- Горутина (G) создается и помещается в локальную очередь P.
- Если P перегружен, часть G перемещается в глобальную очередь.
- M (поток ОС) берет G из очереди P и выполняет. Если P пуст, M может "украсть" G у другого P.
Пример:
func main() {
go func() { fmt.Println("Goroutine 1") }()
go func() { fmt.Println("Goroutine 2") }()
time.Sleep(time.Millisecond) // Даем время на выполнение
}
Прерывания:
- Горутина может быть прервана при вызове блокирующих операций (I/O,
time.Sleep). - Планировщик также использует кооперативную многозадачность – горутина может добровольно уступить управление (
runtime.Gosched()).
Это обеспечивает эффективное использование CPU и низкие накладные расходы.