Ответ
Перемещение горутины из глобальной очереди (GRQ) в локальную (LRQ) является ключевым механизмом балансировки нагрузки в планировщике Go. Процессор (P) забирает горутины из глобальной очереди, когда ему не хватает работы.
Это происходит в следующих ситуациях:
Локальная очередь пуста: Когда процессор (P) выполнил все горутины в своей локальной очереди, он пытается найти новую работу. Первым делом он обращается к глобальной очереди. Если там есть горутины, он забирает одну из них и помещает в свою локальную очередь для исполнения.
Периодическая проверка: Чтобы избежать ситуации, когда горутины в глобальной очереди "голодают" (долго ждут исполнения), планировщик выполняет периодическую проверку. Каждый 61-й тик планировщика процессор (P) обязан проверить глобальную очередь. Если она не пуста, он возьмёт оттуда одну горутину, даже если его собственная локальная очередь еще не закончилась. Это обеспечивает справедливость и предотвращает задержки.
Поиск работы перед "кражей": Если локальная очередь пуста, процессор (P) сначала проверяет глобальную очередь, затем сетевой поллер (
netpoller
), и только если нигде нет готовых горутин, он пытается "украсть" работу у другого процессора (P).
Таким образом, глобальная очередь служит центральным пулом задач, к которому процессоры обращаются, когда у них заканчивается локальная работа или для поддержания общей справедливости в системе.