В планировщике Golang (M) присутствуют следующие сущности:
- M (Machine): Представляет собой поток операционной системы. Отвечает за исполнение G-кода на процессоре. M забирает G из локальной очереди P или обходной очереди.
- P (Processor): Логический процессор (контекст). Содержит локальную очередь готовых к выполнению G. P привязан к M, и только один M может быть привязан к P в любой момент времени. Количество P по умолчанию равно
GOMAXPROCS.
- G (Goroutine): Легковесный поток выполнения. Представляет собой конкурентную функцию или метод. G исполняется на P.
go
go
go
Взаимодействие между сущностями следующее:
- Горутины (G) помещаются в локальные очереди логических процессоров (P).
- Потоки ОС (M) берут P и из их локальных очередей забирают G для выполнения на процессоре.
- Если локальная очередь P пуста, M может попытаться украсть G из локальной очереди другого P (work-stealing).
- При блокирующих системных вызовах, M отвязывается от P, и другой M может занять этот P для выполнения других G. Заблокированный G остается привязанным к отвязавшемуся M.
go
Таким образом, планировщик Golang эффективно использует доступные ядра процессора, распределяя выполнение легковесных горутин между потоками ОС через логические процессоры.