Ответ
Планировщик Go использует модель M:P:G для эффективного управления горутинами. Это позволяет выполнять огромное количество горутин на ограниченном числе потоков операционной системы.
Основные компоненты:
- G (Goroutine): Сама горутина. Это легковесный поток со своим стеком, который может расти и сжиматься. Горутины дешевы в создании.
- M (Machine): Поток операционной системы (OS thread), который непосредственно выполняет код. Управляется ОС.
- P (Processor): Логический процессор, который является контекстом для выполнения Go-кода. Он имеет локальную очередь готовых к выполнению горутин (G). Количество
P
по умолчанию равно количеству ядер ЦП и может быть настроено черезruntime.GOMAXPROCS
.
Как это работает:
- Для выполнения горутины (
G
) планировщик связывает её с логическим процессором (P
). - Затем
P
связывается с потоком ОС (M
) для фактического выполнения кода горутины. - Ключевая особенность: если горутина (
G
) блокируется на системном вызове (например, при чтении файла или сетевом запросе), потокM
также блокируется. В этот момент планировщик может отсоединитьP
от этогоM
и присоединить его к другому, свободномуM
, чтобы продолжить выполнение других горутин из очередиP
. - Когда системный вызов завершается, исходный
M
пытается снова получитьP
для выполнения своей горутины. Если не получается, горутинаG
помещается в глобальную очередь, откуда её может забрать любой свободныйP
.
Эта модель позволяет Go эффективно утилизировать процессорное время, не создавая по потоку ОС на каждую горутину, что делает конкурентность в Go очень производительной.