我对golang很新。
我的理解是,所有的例行程序将同时执行。两个匿名goroutines将同时开始执行。但是当我运行这段代码时,它始终……
我假设你在Playground上运行。使用Go Playground时要记住一件事: 的 它有一个固定的时间和一个固定的psedo随机发生器。 强>
这意味着,您无法使用Playground来观察随机结果。而Goroutine的执行顺序,或Go的并发概念,基于统一的psedo-random-ness。
在我的终端上运行代码会产生不同的结果:
? 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 。
sync
您的代码中只发生一次同步,即通信 c 。它保证了一件事:当 main() goroutine接受了它 Response , 的 至少 强> 在那里产生的其中一个goroutines已经打印出它的“exledated”。
c
main()
Response
的 无法保证哪一个被执行,也没有两个或只有一个被执行,也无法保证goroutine是否会被执行 if 声明包含 panic 第一 强> 。
if
panic
编辑:
进一步阅读:
这些拖车goroutines之间唯一的同步是通过发送 c 。由于只从c中读取一个值,因此只读取两个发送操作中的一个 c <- true 经过而其他人永远阻止。
c <- true
假设第一个goroutine首先运行(偶然),并且发送和两个Printlns,而第二个goroutine根本没有开始执行。这是一种valide操作模式,将产生您看到的输出。
你通过同步 c 是 的 不 强> 在两个匿名的goroutines之间,但在goroutines和外部之间 f3 只要。
f3