Вопрос проверяет понимание того, как Go выполняет горутины и как устроен планировщик runtime.
Модель G-P-M описывает работу планировщика Go.
G — это goroutine, M — системный поток (machine), P — процессор планировщика, который управляет выполнением горутин. Горутины ставятся в очереди, а P распределяет их между потоками M. Это позволяет эффективно использовать CPU и выполнять тысячи горутин.
В Go выполнение кода управляется собственным планировщиком runtime, а не напрямую операционной системой.
Определение:
Модель G-P-M — это архитектура планировщика Go, в которой выполнение горутин отделено от системных потоков.
G — это:
функция, выполняемая конкурентно
собственный стек (начально небольшой, растет динамически)
контекст выполнения
Горутины легковесны, поэтому их может быть десятки и сотни тысяч.
M — это:
реальный поток операционной системы
именно он выполняет код на CPU
Без M код выполняться не может, потому что CPU работает с потоками ОС.
P — это логический процессор планировщика.
Он содержит:
очередь готовых горутин
контекст выполнения
служебные структуры runtime
Количество P обычно равно GOMAXPROCS.
Типичный цикл:
goroutine помещается в очередь P
поток M берет goroutine из P
выполняет ее на CPU
при блокировке горутины планировщик переключается на другую
Упрощенная схема:
Goroutines -> P (очередь) -> M -> CPU
Если бы каждая goroutine была потоком ОС:
огромные накладные расходы
медленное переключение контекста
ограничения ОС
Планировщик Go:
дешевле переключает горутины
лучше масштабируется
позволяет запускать очень много конкурентных задач
Планировщик умеет:
work stealing между P
парковать и будить горутины
освобождать M при блокирующих syscall
Это критично для высокой производительности.
Модель G-P-M позволяет отделить горутины от потоков ОС и эффективно планировать выполнение большого числа конкурентных задач.