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

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

Go 頻道發布、接收和 go 例程調度

Go 頻道發布、接收和 go 例程調度

Go
慕森王 2022-06-27 16:33:34
我有以下一段 go 腳本,我對讀取數據的通道和 go 例程的執行順序有疑問。package mainimport "fmt"func squares(c chan int) {    fmt.Println("started squares goroutine...")    for num := range c {        //num := <-c        fmt.Println(num * num)    }    fmt.Println("exiting squares goroutine...")}func main() {    fmt.Println("main() started")    c := make(chan int, 3)    go squares(c)    c <- 1    printChannel(c)    c <- 2    printChannel(c)    c <- 3    printChannel(c)    c <- 4    fmt.Println("after publish 4")    printChannel(c)    c <- 5    fmt.Println("after publish 5")    printChannel(c)    c <- 6    printChannel(c)    c <- 7    printChannel(c)    c <- 8    printChannel(c)    fmt.Println("main() stopped")}func printChannel(c chan int) {    fmt.Println("length: ",len(c))    fmt.Println("capacity: ",cap(c))    }輸出:main() startedlength:  1capacity:  3length:  2capacity:  3length:  3capacity:  3started squares goroutine...14916after publish 4length:  0capacity:  3after publish 5length:  0capacity:  3length:  1capacity:  3length:  2capacity:  3length:  3capacity:  3main() stopped問題:創建的通道 ch 的容量為 3,但在將 4 發布到通道之前,通道不會在方塊 go 例程中讀取,如果容量為 3,其中 4 存儲在通道中將所有數字從通道中讀取出來后,再次將數字 5 發布到通道,但通道的長度仍然為 0,為什么?代碼的 Goplayground 鏈接:https: //play.golang.org/p/TmCcZt5n58f
查看完整描述

1 回答

?
汪汪一只貓

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

無法保證 goroutine 的執行順序,也無法保證 goroutine 何時中斷(I/O,包括打印到 stdout,將是重新調度的最常見原因)。

對于您的第一個問題:您可以看到16之前正在打印after publish 4。這意味著squaresgoroutine 在主 goroutine 開始打印信息之前從通道讀取并打印正方形。當主 goroutine 嘗試打印通道的長度時,4它已經消失了。

同樣,發送5到通道后,squaresgoroutine 已經收到了,但還沒有打印出來。它在打印之前被中斷。這意味著通道又是空的,但我們還沒有看到25。

如果您多次運行示例,您將看到不同的輸出。有時squaresgoroutine 會一直上升到64,有時不會。這是完全正常的。在普通代碼中,您需要確保在退出之前等待數據被使用,并且您不會依賴于不同 goroutine 的執行順序或時間。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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