Ответ
Горутина помещается в глобальную очередь готовых к исполнению горутин (Global Run Queue, GRQ) в нескольких ключевых ситуациях. Это централизованная очередь, используемая для балансировки нагрузки между процессорами (P).
Основные случаи:
После завершения сетевого I/O: Когда горутина, заблокированная на сетевом вводе-выводе, становится готовой к выполнению, сетевой поллер (
netpoller
) помещает её в глобальную очередь. Это позволяет любому свободному процессору (P) взять её на исполнение, а не ждать тот, на котором она работала изначально.По истечении таймера: Горутины, которые были усыплены с помощью
time.Sleep
или ожидали на таймере, после пробуждения добавляются в глобальную очередь.Добровольная уступка процессора: Явный вызов
runtime.Gosched()
перемещает текущую горутину из локальной очереди в конец глобальной, позволяя другим горутинам выполниться.После длительного системного вызова: Если горутина блокируется на системном вызове, её процессор (P) может быть передан другой M (потоку ОС) для выполнения других горутин. Когда исходная горутина разблокируется, она часто помещается в глобальную очередь.
Использование глобальной очереди помогает предотвратить простой процессоров (P) и обеспечивает более справедливое распределение работы по системе.