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个goroutine来将num插入通道c,所以我只是想知道,这些goroutines会以随机顺序执行吗?在我的测试期间,输出将始终为1到100
答案 0 :(得分:8)
不,他们不能保证按顺序运行。使用GOMAXPROCS=1
(默认值)它们会出现,但语言规范无法保证这一点。
当我使用GOMAXPROCS=6
运行程序时,输出是不确定的:
$ GOMAXPROCS=6 ./test
2
0
1
4
3
5
6
7
8
9
...
在另一次运行中,输出略有不同。
如果您希望通道上的一组发送按顺序发生,最好的解决方案是从同一个goroutine执行它们。
答案 1 :(得分:5)
你观察到的是&#34;随机&#34;行为更严格地说是非确定性行为。
要了解此处发生的事情,请考虑频道的行为。在这种情况下,它有许多尝试写入频道的goroutine,只有一个goroutine读出频道。
阅读过程简单顺序,我们可以忽略它。
有许多并发写入过程,他们竞争访问共享资源(通道)。频道必须选择接受哪条消息。
当通信顺序流程(CSP)网络进行 选择 时,会引入 非确定性 。在Go中,有两种方式可以实现这种选择:
select
陈述。您的案例是第一个。
CSP是一种代数,可以分析和理解并发行为。关于这一点的开创性出版物是Roscoe和Hoare&#34; 奥卡姆编程法则&#34; https://www.cs.ox.ac.uk/files/3376/PRG53.pdf(类似的想法也适用于Go,尽管存在细微的差异)。
令人惊讶的是,goroutines的并发执行是完全确定性的。只有在做出选择时才会出现非决定论。