Ответ
Локальная очередь (Local Run Queue, LRQ) привязана к конкретному логическому процессору (P) и является основным местом, куда попадают горутины. Это сделано для минимизации блокировок и повышения производительности.
Основные случаи:
-
Создание новой горутины: Когда вы создаете новую горутину с помощью
go func()
, она в первую очередь помещается в локальную очередь текущего процессора (P). Это самый частый и эффективный сценарий.go func() { // Эта горутина с высокой вероятностью попадёт // в локальную очередь текущего процессора P. fmt.Println("Hello from a new goroutine!") }()
-
Разблокировка на канале: Когда горутина, заблокированная на операции с каналом (чтение или запись), разблокируется, она помещается напрямую в локальную очередь того процессора (P), на котором исполнялась горутина, выполнившая парную операцию. Это оптимизация, известная как "hand-off".
-
После "кражи работы" (Work Stealing): Если у процессора (P) заканчиваются горутины в его локальной очереди, он может "украсть" половину горутин из локальной очереди другого, более загруженного процессора. Украденные горутины помещаются в его собственную локальную очередь.
-
Возврат управления после вытеснения: Если горутина была вытеснена планировщиком (например, выполнялась слишком долго без блокировок), она возвращается в локальную очередь своего же процессора (P).