package mainfunc 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
2 回答
慕侠2389804
TA贡献1719条经验 获得超6个赞
不,它们不能保证按顺序运行。使用GOMAXPROCS=1(默认)它们似乎是,但这不是语言规范所保证的。
当我用 运行你的程序时GOMAXPROCS=6,输出是不确定的:
$ GOMAXPROCS=6 ./test
2
0
1
4
3
5
6
7
8
9
...
在另一次运行中,输出略有不同。
如果您希望在一个通道上按顺序进行一组发送,最好的解决方案是从同一个 goroutine 中执行它们。
潇湘沐
TA贡献1816条经验 获得超6个赞
您观察到的“随机”行为更严格地说是非确定性行为。
要了解此处发生的情况,请考虑通道的行为。在这种情况下,它有许多 goroutine 试图写入通道,只有一个 goroutine 读取通道。
阅读过程只是顺序的,我们可以忽略它。
有许多并发写入进程,它们竞争访问共享资源(通道)。通道必须选择它接受的消息。
当通信顺序过程 (CSP) 网络做出选择时,它引入了非确定性。在 Go 中,这种选择有两种发生方式:
对通道一端的并发访问,以及
select
声明。
你的情况是第一个。
CSP 是一种代数,允许分析和理解并发行为。这方面的开创性出版物是 Roscoe 和 Hoare “奥卡姆编程法则” https://www.cs.ox.ac.uk/files/3376/PRG53.pdf(类似的想法也适用于 Go,尽管有一些小的差异)。
令人惊讶的是,goroutine 的并发执行是完全确定的。这是只有当选择由非确定性的用武之地。
- 2 回答
- 0 关注
- 251 浏览
添加回答
举报
0/150
提交
取消