为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
呼唤远方 2021-09-21 16:59:12
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 中执行它们。


查看完整回答
反对 回复 2021-09-21
?
潇湘沐

TA贡献1816条经验 获得超6个赞

您观察到的“随机”行为更严格地说是非确定性行为。

要了解此处发生的情况,请考虑通道的行为。在这种情况下,它有许多 goroutine 试图写入通道,只有一个 goroutine 读取通道。

阅读过程只是顺序的,我们可以忽略它。

有许多并发写入进程,它们竞争访问共享资源(通道)。通道必须选择它接受的消息。

当通信顺序过程 (CSP) 网络做出选择时,它引入了非确定性。在 Go 中,这种选择有两种发生方式:

  • 对通道一端的并发访问,以及

  • select 声明。

你的情况是第一个。

CSP 是一种代数,允许分析和理解并发行为。这方面的开创性出版物是 Roscoe 和 Hoare “奥卡姆编程法则” https://www.cs.ox.ac.uk/files/3376/PRG53.pdf(类似的想法也适用于 Go,尽管有一些小的差异)。

令人惊讶的是,goroutine 的并发执行是完全确定的。这是只有当选择由非确定性的用武之地。


查看完整回答
反对 回复 2021-09-21
  • 2 回答
  • 0 关注
  • 251 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信