猿问

在同一个 goroutine 中创建的 goroutine 是否总是按顺序执行?

package main


func main() {

        c:=make(chan int)

        for i:=0; i<=100;i++ {

                i:=i

                go func() {

                        c<-i

                }() 

        }   

        for {

                b:=<-c

                println(b)

                if b==100 {

                        break

                }   

        }   

}

上面的代码创建了 100 个 goroutines 将 num 插入到 channel c,所以我想知道,这些 goroutines 会以随机顺序执行吗?在我的测试期间,输出将始终为 1 到 100


呼唤远方
浏览 252回答 2
2回答

慕侠2389804

不,它们不能保证按顺序运行。使用GOMAXPROCS=1(默认)它们似乎是,但这不是语言规范所保证的。当我用 运行你的程序时GOMAXPROCS=6,输出是不确定的:$ GOMAXPROCS=6 ./test2014356789...在另一次运行中,输出略有不同。如果您希望在一个通道上按顺序进行一组发送,最好的解决方案是从同一个 goroutine 中执行它们。

潇湘沐

您观察到的“随机”行为更严格地说是非确定性行为。要了解此处发生的情况,请考虑通道的行为。在这种情况下,它有许多 goroutine 试图写入通道,只有一个 goroutine 读取通道。阅读过程只是顺序的,我们可以忽略它。有许多并发写入进程,它们竞争访问共享资源(通道)。通道必须选择它接受的消息。当通信顺序过程 (CSP) 网络做出选择时,它引入了非确定性。在 Go 中,这种选择有两种发生方式:对通道一端的并发访问,以及select&nbsp;声明。你的情况是第一个。CSP 是一种代数,允许分析和理解并发行为。这方面的开创性出版物是 Roscoe 和 Hoare “奥卡姆编程法则”&nbsp;https://www.cs.ox.ac.uk/files/3376/PRG53.pdf(类似的想法也适用于 Go,尽管有一些小的差异)。令人惊讶的是,goroutine 的并发执行是完全确定的。这是只有当选择由非确定性的用武之地。
随时随地看视频慕课网APP

相关分类

Go
我要回答