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