В каких случаях горутина попадает в глобальную очередь планировщика?

Ответ

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

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


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



  2. По истечении таймера: Горутины, которые были усыплены с помощью time.Sleep или ожидали на таймере, после пробуждения добавляются в глобальную очередь.



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



  4. После длительного системного вызова: Если горутина блокируется на системном вызове, её процессор (P) может быть передан другой M (потоку ОС) для выполнения других горутин. Когда исходная горутина разблокируется, она часто помещается в глобальную очередь.


Использование глобальной очереди помогает предотвратить простой процессоров (P) и обеспечивает более справедливое распределение работы по системе.