Почему иногда не работает runtime.Gosched? - PullRequest
0 голосов
/ 16 июня 2020

Мой клиент довольно простой. Также есть две горутины:

  1. Основная горутина: вызовите runtime.Gosched, затем выведите «1».
  2. Вторая горутина: выведите «2».
package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(1)
    go func() {
        fmt.Println(2)
    }()

    runtime.Gosched()
    fmt.Println(1)
}

Вначале я вызываю метод runtime.GOMAXPROCS, чтобы установить P count равным 1, поэтому все горутины будут работать в одном потоке.

Когда я вызываю runtime.Gosched, второй goroutine получит шанс запустить, поэтому сначала напечатайте 2, а затем распечатайте 1.

Но иногда печатается только 1, я хочу знать, почему?

Моя Golang версия - go1. 14,1

1 Ответ

2 голосов
/ 16 июня 2020

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

Короче говоря, runtime.Gosched() не гарантирует, как долго может работать запланированная горутина. Горутина main может быть перепланирована до того, как другая горутина сможет «полностью» выполнить операцию печати. И если это произойдет и горутина main завершится, ваше приложение тоже завершится (в этом случае вы не увидите напечатанного 2, а только 1 из main).

runtime.Gosched() не может использоваться для управления планированием горутины, его можно использовать только для того, чтобы горутина не монополизировала поток, в котором она выполняется.

runtime.Gosched() не является инструментом синхронизации. Если вам нужно дождаться других запущенных горутин, используйте sync.WaitGroup, например:

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    fmt.Println(2)
}()

fmt.Println(1)
wg.Wait()

Если запущенная горутина должна запускаться первой (до main), тогда нет смысла запускать это как отдельная горутина, выполните работу на main:

fmt.Println(2)

fmt.Println(1)
...