В каких случаях горутина попадает в локальную очередь процессора (P)?

Ответ

Локальная очередь (Local Run Queue, LRQ) привязана к конкретному логическому процессору (P) и является основным местом, куда попадают горутины. Это сделано для минимизации блокировок и повышения производительности.

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

  1. Создание новой горутины: Когда вы создаете новую горутину с помощью go func(), она в первую очередь помещается в локальную очередь текущего процессора (P). Это самый частый и эффективный сценарий.

    go func() {
        // Эта горутина с высокой вероятностью попадёт
        // в локальную очередь текущего процессора P.
        fmt.Println("Hello from a new goroutine!")
    }()
  2. Разблокировка на канале: Когда горутина, заблокированная на операции с каналом (чтение или запись), разблокируется, она помещается напрямую в локальную очередь того процессора (P), на котором исполнялась горутина, выполнившая парную операцию. Это оптимизация, известная как "hand-off".

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

  4. Возврат управления после вытеснения: Если горутина была вытеснена планировщиком (например, выполнялась слишком долго без блокировок), она возвращается в локальную очередь своего же процессора (P).