我對GoLang世界很陌生,并且正在嘗試goroutines/頻道。據我所知,渠道是戈魯丁之間的雙向溝通方式。如果我們創建一個長度為 0 的通道,它應該是一個同步通道,它表示除非某些 goroutine(即使用者)從通道讀取值,否則生產者將無法前進。我嘗試了下面的示例來測試這一點,但我沒有得到預期的結果。package mainimport ( "fmt" "time")var done = make(chan bool)var msgs = make(chan int)func produce() { for i := 0; i < 40; i++ { //fmt.Println("sending") fmt.Println("Produced: ", i) msgs <- i //fmt.Println("Channel size is: ", len(msgs)) } fmt.Println("Before closing channel") close(msgs) fmt.Println("Before passing true to done") }func consume() { for msg := range msgs { //fmt.Println("Going to take one, Channel size is: ", len(msgs)) fmt.Println("Consumer: ", msg) time.Sleep(100 * time.Millisecond) } done <- true }func main() { go produce() go consume() <-done fmt.Println("After calling DONE")}輸出:Produced: 0Produced: 1Consumer: 0Consumer: 1Produced: 2Consumer: 2...我期望輸出Produced: 0Consumer: 0Produced: 1Consumer: 1Produced: 2Consumer: 2請幫我在這里指出我做錯了什么?
1 回答

子衿沉夜
TA貢獻1828條經驗 獲得超3個贊
(無緩沖)通道讀取/寫入將按照您期望的順序進行:一次寫入;一讀;一寫;一次閱讀等。
但是,生產者/消費者 goroutines 中的調用是不同步的 - 因此,生產者可以在 之前將其功能放入調度程序中。fmt.Println
fmt.Println
consumer
由于睡眠 - 它自愿向調度程序提供提示,讓其他goroutines跑在它前面。因此,最有可能總是在醒來之前進行第二次運行。consumer
producer
fmt.Println
consumer
如果你把睡眠移到gooutine,你可以看到你在操場上的預期行為:https://play.golang.org/p/5x9_yyUaMiJ - 但是你不應該依賴這些計時技巧。如果要確保一個函數相對于另一個 goroutine 的執行順序,這些任務也必須同步。通過通道讀取/寫入 - 只有讀取/寫入保證是安全的和順序的。producer
- 1 回答
- 0 關注
- 98 瀏覽
添加回答
舉報
0/150
提交
取消