在同一个 goroutines 中创建的 goroutines 是否总是按顺序执行?
Does the goroutines created in the same goroutines execute always in order?
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插入通道c,所以我想知道,这些goroutines会随机执行吗?在我的测试中,输出总是 1 到 100
不,不能保证它们 运行 的顺序。使用 GOMAXPROCS=1
(默认值)时,它们似乎是,但语言规范不能保证这一点。
当我 运行 你的程序 GOMAXPROCS=6
时,输出是不确定的:
$ GOMAXPROCS=6 ./test
2
0
1
4
3
5
6
7
8
9
...
在另一个 运行 上,输出略有不同。
如果您希望通道上的一组发送按顺序发生,最好的解决方案是从同一个 goroutine 执行它们。
您观察到的 "random" 行为,更严格地说,是非确定性行为。
要了解此处发生的情况,请考虑通道的行为。在这种情况下,它有很多 goroutines 试图写入通道,只有一个 goroutines 从通道中读出。
读取过程只是顺序的,我们可以忽略。
有很多并发写入进程,它们正在竞争访问共享资源(通道)。频道必须选择要接受的消息。
当通信顺序过程 (CSP) 网络做出选择时,它引入了非确定性。在 Go 中,这种选择有两种方式:
- 并发访问通道的一端,并且
select
个语句。
你的情况是第一个。
CSP 是一种允许分析和理解并发行为的代数。关于此的开创性出版物是 Roscoe 和 Hoare“Occam 编程法则”https://www.cs.ox.ac.uk/files/3376/PRG53.pdf(类似的想法也适用于 Go,尽管存在细微差别)。
令人惊讶的是,goroutines 的并发执行是完全确定的。 只有在做出选择时,非确定性才会出现。
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插入通道c,所以我想知道,这些goroutines会随机执行吗?在我的测试中,输出总是 1 到 100
不,不能保证它们 运行 的顺序。使用 GOMAXPROCS=1
(默认值)时,它们似乎是,但语言规范不能保证这一点。
当我 运行 你的程序 GOMAXPROCS=6
时,输出是不确定的:
$ GOMAXPROCS=6 ./test
2
0
1
4
3
5
6
7
8
9
...
在另一个 运行 上,输出略有不同。
如果您希望通道上的一组发送按顺序发生,最好的解决方案是从同一个 goroutine 执行它们。
您观察到的 "random" 行为,更严格地说,是非确定性行为。
要了解此处发生的情况,请考虑通道的行为。在这种情况下,它有很多 goroutines 试图写入通道,只有一个 goroutines 从通道中读出。
读取过程只是顺序的,我们可以忽略。
有很多并发写入进程,它们正在竞争访问共享资源(通道)。频道必须选择要接受的消息。
当通信顺序过程 (CSP) 网络做出选择时,它引入了非确定性。在 Go 中,这种选择有两种方式:
- 并发访问通道的一端,并且
select
个语句。
你的情况是第一个。
CSP 是一种允许分析和理解并发行为的代数。关于此的开创性出版物是 Roscoe 和 Hoare“Occam 编程法则”https://www.cs.ox.ac.uk/files/3376/PRG53.pdf(类似的想法也适用于 Go,尽管存在细微差别)。
令人惊讶的是,goroutines 的并发执行是完全确定的。 只有在做出选择时,非确定性才会出现。