【问题标题】:Why is runtime.Gosched not working sometimes?为什么 runtime.Gosched 有时不工作?
【发布时间】:2020-06-16 10:40:54
【问题描述】:

我的客户相当简单。还有两个 goroutine:

  1. 主 goroutine:调用 runtime.Gosched,然后打印“1”。
  2. 第二个 goroutine:打印“2”。
package main

import (
    "fmt"
    "runtime"
)

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

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

一开始,我调用方法 runtime.GOMAXPROCS 将 P 计数设置为 1,这样所有的 goroutine 都会运行在同一个线程上。

当我调用 runtime.Gosched 时,第二个 goroutine 将有机会运行,所以先打印 2,然后再打印 1。

但有时,只打印1个,我想知道为什么?

我的 Golang 版本是 go1.14.1

【问题讨论】:

  • "当我调用 runtime.Gosched 时,第二个 goroutine 将有机会运行" 正确。请注意“运行的机会”!=“确实运行”。

标签: go concurrency goroutine


【解决方案1】:

runtime.Gosched() 不会“取消优先级”调用它的 goroutine,它只是将处理器让给其他 goroutine。调用者 goroutine 保持活动状态,可能会被安排再次运行。

所以简而言之,runtime.Gosched() 不保证调度的 goroutine 可以运行多长时间。 main goroutine 可能会在另一个 goroutine 可以“完全”执行打印操作之前重新调度。如果发生这种情况并且 main goroutine 结束,您的应用程序也会结束(在这种情况下,您将看不到 2 打印,只会看到来自 main1)。

runtime.Gosched() 不能用于控制 goroutine 的调度,只能用于让 goroutine 不独占它运行的线程。

runtime.Gosched() 不是同步工具。如果您必须等待其他启动的 goroutines,请使用 sync.WaitGroup 例如:

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

fmt.Println(1)
wg.Wait()

如果启动的 goroutine 必须首先运行(在 main 之前),那么将其作为单独的 goroutine 运行是没有意义的,请在 main 上执行此工作:

fmt.Println(2)

fmt.Println(1)

【讨论】:

    猜你喜欢
    • 2012-10-17
    • 2014-03-28
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2017-10-14
    相关资源
    最近更新 更多