亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

goroutines的執行順序

goroutines的執行順序

Go
一只斗牛犬 2023-06-12 15:28:40
我對 golang 很陌生。我的理解是,所有的go-routines都會同時執行。兩個匿名 goroutines 將同時開始執行。但是當我運行這段代碼時,它總是打印出來a=1 first executeda=1 second executedpanic: b != 1不應該打印嗎a = 1a = 1 first executed Response trueand so on或者b =1 b = 1 first executed Response trueand so on既然向通道發送了一個值之后,相應的goroutine應該阻塞并等待接收者? func main() {            var a, b int            var c = make(chan bool)            go func() {                b = 1                fmt.Println("b=1 first executed")                c <- true                fmt.Println("b=1 second executed")                if a != 1 { // impossible                    panic("a != 1") // will never happen                }                fmt.Println("b=1 third executed")            }()            go func() {                a = 1                fmt.Println("a=1 first executed")                c <- true                fmt.Println("a=1 second executed")                if b != 1 { // impossible                    panic("b != 1") // will never happen                }                fmt.Println("a=1 third executed")            }()            fmt.Println("Response ", <-c)            fmt.Println("Main executed")            }
查看完整描述

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。


查看完整回答
反對 回復 2023-06-12
?
森林海

TA貢獻2011條經驗 獲得超2個贊

這些兩個 goroutine 之間的唯一同步是通過 send on c。由于從 c 中只讀取了一個值,因此兩個發送操作中只有一個c <- true通過,而另一個永遠阻塞。

讓我們假設第一個 goroutine 首先運行(偶然),然后執行發送和兩個 Printlns,而第二個 goroutine 根本沒有開始執行。這是一種有效的操作模式,將產生您看到的輸出。

您的同步c不是兩個匿名 goroutine 之間,而是在 goroutine 和外部 goroutine 之間f3。


查看完整回答
反對 回復 2023-06-12
  • 2 回答
  • 0 關注
  • 221 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號