我有以下一段 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
。這意味著squares
goroutine 在主 goroutine 開始打印信息之前從通道讀取并打印正方形。當主 goroutine 嘗試打印通道的長度時,4
它已經消失了。
同樣,發送5
到通道后,squares
goroutine 已經收到了,但還沒有打印出來。它在打印之前被中斷。這意味著通道又是空的,但我們還沒有看到25
。
如果您多次運行示例,您將看到不同的輸出。有時squares
goroutine 會一直上升到64
,有時不會。這是完全正常的。在普通代碼中,您需要確保在退出之前等待數據被使用,并且您不會依賴于不同 goroutine 的執行順序或時間。
- 1 回答
- 0 關注
- 117 瀏覽
添加回答
舉報
0/150
提交
取消