Как горутина перемещается из глобальной очереди в локальную?

Ответ

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

Это происходит в следующих ситуациях:


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



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



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


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