2 回答
TA贡献2016条经验 获得超9个赞
我假设你在 Playground 上跑步。使用 Go Playground 时要记住一件事:它有一个固定的时间和一个固定的伪随机生成器。
这意味着,您不能使用 Playground 来观察随机结果。而 Goroutine 的执行顺序,或者一般来说是 Go 的并发概念,是基于统一的伪随机性。
在我的终端上运行你的代码,它会产生不同的结果:
➜ basic1 GOMAXPROCS=1 ./basic1
a=1 first executed
a=1 second executed
a=1 third executed
Response true
Main executed
➜ basic1 GOMAXPROCS=1 ./basic1
a=1 first executed
a=1 second executed
panic: b != 1
goroutine 6 [running]:
main.main.func2(0xc000012088, 0xc000054060, 0xc0000120a0)
/mnt/f/home/leaf/spike/stackoverflow/concur/basic1/main.go:26 +0x13b
created by main.main
/mnt/f/home/leaf/spike/stackoverflow/concur/basic1/main.go:20 +0xed
➜ basic1 GOMAXPROCS=1 ./basic1
a=1 first executed
a=1 second executed
a=1 third executed
b=1 first executed
Response true
Main executed
但还有更多。正如我提到的,Go 的并发执行顺序是随机的。除非有同步,否则无法保证哪个先进行。
同步包括通道通信和来自sync.
您的代码中只发生一种同步,即通过c. 它保证了一件事:当main()goroutine 收到它时Response,至少有一个在那里生成的 goroutines 打印了它的“excecuated”。
不能保证执行其中一个,也不保证执行两个或只执行一个,也不保证 goroutine 是否命中包含first 的if语句panic。
TA贡献2011条经验 获得超2个赞
这些两个 goroutine 之间的唯一同步是通过 send on c
。由于从 c 中只读取了一个值,因此两个发送操作中只有一个c <- true
通过,而另一个永远阻塞。
让我们假设第一个 goroutine 首先运行(偶然),然后执行发送和两个 Printlns,而第二个 goroutine 根本没有开始执行。这是一种有效的操作模式,将产生您看到的输出。
您的同步c
不是在两个匿名 goroutine 之间,而是在 goroutine 和外部 goroutine 之间f3
。
- 2 回答
- 0 关注
- 164 浏览
添加回答
举报