В каких случаях горутина попадает в глобальную очередь выполнения (Global Run Queue)?

Ответ

Горутина может попасть в глобальную очередь выполнения (GRQ) в нескольких сценариях. GRQ используется планировщиком Go как общий пул задач, к которому обращаются процессоры (P), когда их локальные очереди пусты.

Основные случаи:


  1. После завершения системного или сетевого вызова. Когда горутина, заблокированная на I/O операции (например, чтение из сети), становится готовой к выполнению, она часто помещается в глобальную очередь, чтобы любой свободный процессор (P) мог её забрать.



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



  3. При явном вызове runtime.Gosched(). Этот вызов добровольно уступает процессорное время, и текущая горутина перемещается в глобальную очередь, давая возможность выполниться другим горутинам.



  4. При создании горутин (редко). Новые горутины в первую очередь попадают в локальную очередь текущего процессора (P). В глобальную они могут попасть, если локальная очередь переполнена, что на практике случается нечасто.


Работа с глобальной очередью менее эффективна, чем с локальной, так как требует использования глобального мьютекса для синхронизации доступа, что может приводить к состоянию гонки (contention) при высокой нагрузке.