Middle+
102
questionbank

Расскажи о паттерне управления горутинами (GMP) в Go.

Получайте ответы на вопросы в реальном времени с Sobes Copilot
Ответ от нейросети sobes.tech

Планировщик Go управляет горутинами, потоками операционной системы и логическими процессорами, используя модель GMP:

  • G (Goroutine): Легковесная, независимая единица выполнения. Содержит стек, указатель на инструкцию и другую информацию о состоянии. Множество горутин могут работать на одном потоке ОС.
  • M (Machine): Поток операционной системы. Выступает в роли исполнителя, запускающего код горутины. Множество M может быть доступно для планировщика.
  • P (Processor): Логический процессор. Предоставляет контекст для выполнения горутины. Содержит локальную очередь горутин, которые готовы к выполнению на данном M. Количество P по умолчанию равно runtime.NumCPU().

Взаимодействие:

  1. Горутина (G) создается и помещается в глобальную или локальную очередь P.
  2. Свободный поток M запрашивает P. Если P доступен, M привязывается к нему.
  3. M берет горутину из локальной очереди P и начинает ее выполнение.
  4. Если горутина блокируется (например, при ожидании I/O), M отсоединяется от P ("hand off"). P остается доступным для другого M или планирует другую горутину из своей очереди.
  5. Когда блокированная горутина готова к возобновлению, она помещается обратно в очередь P или глобальную очередь.
  6. M может быть создан планировщиком при необходимости (например, если все существующие M заблокированы) или удален при неактивности.

Preemption (принудительное переключение): Планировщик может прервать выполнение горутины после определенного периода времени (time slice), чтобы гарантировать справедливое распределение процессорного времени между другими горутинами.

Work Stealing (кража работы): Если P исчерпал горутины в своей локальной очереди, он может попытаться "украсть" горутины из глобальной очереди или очередей других P.