Объясните модель планирования горутин в Go (модель M, P, G).

Ответ

Планировщик Go использует модель M:P:G для эффективного управления горутинами. Это позволяет выполнять огромное количество горутин на ограниченном числе потоков операционной системы.

Основные компоненты:

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

Как это работает:

  1. Для выполнения горутины (G) планировщик связывает её с логическим процессором (P).
  2. Затем P связывается с потоком ОС (M) для фактического выполнения кода горутины.
  3. Ключевая особенность: если горутина (G) блокируется на системном вызове (например, при чтении файла или сетевом запросе), поток M также блокируется. В этот момент планировщик может отсоединить P от этого M и присоединить его к другому, свободному M, чтобы продолжить выполнение других горутин из очереди P.
  4. Когда системный вызов завершается, исходный M пытается снова получить P для выполнения своей горутины. Если не получается, горутина G помещается в глобальную очередь, откуда её может забрать любой свободный P.

Эта модель позволяет Go эффективно утилизировать процессорное время, не создавая по потоку ОС на каждую горутину, что делает конкурентность в Go очень производительной.