在 Select 语句的默认情况下使用 runtime.Gosched() 是否有意义?

Go的文档说


Gosched 产生处理器,允许其他 goroutines 运行。它不会暂停当前的 goroutine,因此执行会自动恢复。


基于该定义,如果我有一系列同时创建和执行的长时间运行的 go 例程,那么以下列方式编写 select 语句是否有利:


for {

    select {

        case msg := <- msgch : 

            fmt.Println(msg)

        default: 

            runtime.Gosched()

    }

我假设根据文档,这段代码会导致运行更多的 go 例程。我的假设正确吗?


30秒到达战场
浏览 100回答 2
2回答

catspeake

不,这里没有必要,因为每当 Go 在等待通道或等待 I/O 时,它允许其他 goroutines 自动运行。自 Go 1.0 以来就是这种情况。在Go 1.2中,Go 运行时的调度程序会在您调用函数时添加自动抢占点。在此之前,如果你有一个 CPU 绑定循环(即使有一个函数调用),它可能会使调度程序饿死,你可能需要runtime.Gosched.然后在Go 1.14中,他们使运行时的这方面变得更好,甚至没有函数调用的紧密 CPU 绑定循环也会自动被抢占。因此,对于任何 Go 版本,您都不需要runtime.Gosched在等待通道或 I/O 时调用;在 1.14 之前,如果您正在进行长时间运行的计算,您可能想调用它。但是对于 Go 1.14+,我不明白为什么你需要手动调用它。如果我正在审查您的实际代码,我建议将其更改为一个简单的for ... range循环:for&nbsp;msg&nbsp;:=&nbsp;range&nbsp;msgCh&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;fmt.Println(msg) }这将等待每条消息进入并打印它,如果/当通道关闭时停止。switch但是,如果您正在等待另一个通道或完成信号,例如上下文,您会想要一个。是这样的:for {&nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case msg := <- msgCh:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(msg)&nbsp; &nbsp; &nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }}

梦里花落0921

使用runtime.Gosched()[anywhere] 有意义吗?不。使用 Gosched 基本上不需要或不明智。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go