[英]Golang concurrency and blocking with a single channel, explanation needed
我正在玩https://tour.golang.org/concurrency/5上提供的代碼。 我的想法是,我可以擺脫退出通道來簡化代碼,並且仍然保持正確的程序行為-僅出於學習目的。
這是我得到的代碼(為了獲得更好的可讀性,對其進行了進一步簡化):
package main
import "fmt"
import "time"
func sendNumbers(c chan int) {
for i := 0; i < 2; i++ {
c <- i
}
}
func main() {
c := make(chan int)
go func() {
for i := 0; i < 2; i++ {
fmt.Println(<-c)
}
}()
time.Sleep(0 * time.Second)
sendNumbers(c)
}
在此代碼中,我產生的go例程應該能夠在返回之前接收2個數字。 我接下來調用的sendNumbers()函數將恰好2個數字發送到通道c。
因此,該程序的預期輸出為2行:0和1。但是,當我在頁面上運行代碼時,我得到的只是包含0的一行。
注意
time.Sleep(0 * time.Second)
盡管我是在調用sendNumbers(c)之前故意添加的。 如果我將其更改為
time.Sleep(1 * time.Second)
輸出變為預期:
0
1
所以,我對發生的事情感到困惑。 有人可以解釋發生了什么嗎? 無論在調用sendNumbers()之前經過了多長時間,發送和接收塊都不應同時發送嗎?
在Go中,無論其他goroutine是否仍在運行,只要主函數返回,程序都會立即退出。 如果要確保main函數不會過早退出,則需要某種同步機制。 https://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/
您不必絕對必須使用同步原語,也可以只使用通道來完成,可以說是一種更慣用的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.