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

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

為什么有些頻道操作會阻塞而有些不會

為什么有些頻道操作會阻塞而有些不會

Go
陪伴而非守候 2022-06-01 17:28:04
我一直看到一些文章(和 golang 自己的文檔)描述通道操作的方式與我在現實中看到的不一致。它與 Go 如何阻塞通道讀/寫有關。我現在在多個地方讀到,當一個 goroutine 看到對通道的讀取或寫入時,它會阻止執行,這意味著它要么等待接收數據,要么等待另一個 goroutine 從通道接收數據。但是,如果您查看以下示例,這顯然不是第二次寫入發生的情況。package mainimport (    "fmt")func firstFunc(ch chan string) {    fmt.Println("firstFunc Hello", <-ch)    fmt.Println("firstFunc() carries on getting called")}func secondFunc(ch chan string) {    fmt.Println("secondFunc Hello", <-ch)    fmt.Println("secondFunc() carries on getting called")}func main() {    fmt.Println("main() started")    c1 := make(chan string)    c2 := make(chan string)    go firstFunc(c1)    go secondFunc(c2)    c1 <- "John"    c2 <- "Bob"    fmt.Println("main() ended")}這就是我解釋 Go 執行此代碼的方式:它打印 main() 開始的消息,創建通道 c1 和 c2 并將 firstFunc 和 secondFunc goroutine 排隊(但此時不執行它們)它到達 c1 <- "John" 并阻止它,直到另一個 goroutine 從該通道讀取此時它調度 firstFunc 從 c1 讀取并繼續執行其余代碼直到函數結束main() 再次被重新安排,下一行是 C2 <- "Bob",此時我認為 main() 應該再次阻塞,就像它對 "John" 所做的那樣,并等待 secondFunc 在繼續之前從中讀取。但這不是發生的事情。輸出:main() startedfirstFunc Hello JohnfirstFunc() carries on getting calledmain() ended它不會簡單地阻止對“Bob”的寫入,而是繼續執行直到 main() 完成并且從不調度 secondFunc?,F在這已經成為我學習 Go 的一個障礙,因為我不確定是我不能信任的文章還是我的理解存在差距。我將不勝感激這方面的一些幫助。
查看完整描述

3 回答

?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

一個無緩沖的通道寫入將阻塞,直到另一個 goroutine 從中讀取。發生這種情況時,讀取和寫入 goroutine 都會啟用。之后,無法保證執行將如何進行。

在您的示例中,firstFunc從通道讀取后,它會運行直到完成。主 goroutine 寫入通道 2,啟用secondFunc,但在它有機會完成寫入之前,主 goroutine 結束。

這里的問題是有許多可能的執行順序,而您碰巧觀察到一種特定的順序。


查看完整回答
反對 回復 2022-06-01
?
largeQ

TA貢獻2039條經驗 獲得超8個贊

您看不到輸出,secondFunc因為 main 在它有機會執行之前就結束了。解決此問題的一種簡單方法是time.Sleep(time.Second)在打印“main() 結束”之前添加。


更正確的方法是使用等待組,如下所示:


wg := sync.WaitGroup{}

wg.Add(2)

go func() { firstFunc(c1); wg.Done() }()

go func() { secondFunc(c2); wg.Done() }()

... // write to channels

wg.Wait() // This blocks till both the go-routines are done


查看完整回答
反對 回復 2022-06-01
?
長風秋雁

TA貢獻1757條經驗 獲得超7個贊

它不會因為有 2 個通道偵聽器(firstFunc 和 secondFunc)而阻塞。這些以隨機順序閱讀您的消息(以先醒來者為準)。所以阻塞是存在的,但對于活躍的聽眾來說是無法觀察到的。您唯一會看到的是,有時您會首先看到 firstFunc 的輸出,有時您會看到 secondFunc 的輸出



查看完整回答
反對 回復 2022-06-01
  • 3 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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