2 回答

TA貢獻(xiàn)2016條經(jīng)驗 獲得超9個贊
我假設(shè)你在 Playground 上跑步。使用 Go Playground 時要記住一件事:它有一個固定的時間和一個固定的偽隨機生成器。
這意味著,您不能使用 Playground 來觀察隨機結(jié)果。而 Goroutine 的執(zhí)行順序,或者一般來說是 Go 的并發(fā)概念,是基于統(tǒng)一的偽隨機性。
在我的終端上運行你的代碼,它會產(chǎn)生不同的結(jié)果:
?? 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 的并發(fā)執(zhí)行順序是隨機的。除非有同步,否則無法保證哪個先進(jìn)行。
同步包括通道通信和來自sync.
您的代碼中只發(fā)生一種同步,即通過c. 它保證了一件事:當(dāng)main()goroutine 收到它時Response,至少有一個在那里生成的 goroutines 打印了它的“excecuated”。
不能保證執(zhí)行其中一個,也不保證執(zhí)行兩個或只執(zhí)行一個,也不保證 goroutine 是否命中包含first 的if語句panic。

TA貢獻(xiàn)2011條經(jīng)驗 獲得超2個贊
這些兩個 goroutine 之間的唯一同步是通過 send on c
。由于從 c 中只讀取了一個值,因此兩個發(fā)送操作中只有一個c <- true
通過,而另一個永遠(yuǎn)阻塞。
讓我們假設(shè)第一個 goroutine 首先運行(偶然),然后執(zhí)行發(fā)送和兩個 Printlns,而第二個 goroutine 根本沒有開始執(zhí)行。這是一種有效的操作模式,將產(chǎn)生您看到的輸出。
您的同步c
不是在兩個匿名 goroutine 之間,而是在 goroutine 和外部 goroutine 之間f3
。
- 2 回答
- 0 關(guān)注
- 212 瀏覽
添加回答
舉報