[英]Golang inbound channel not receiving inside a goroutine
請幫助我了解為什么在這種情況下為什么未<-done
入站<-done
頻道?
func main() {
done := make(chan bool)
println("enter")
defer func() {
println("exit")
}()
defer func() {
println(" notify start")
done <- true
println(" notify end")
}()
go func() {
println(" wait start")
<-done
println(" wait end")
}()
time.Sleep(time.Millisecond) // << when this is removed, it works.
}
我期望輸出為:
enter
notify start
wait start
wait end
notify end
exit
而是:
enter
wait start
notify start
notify end
exit
最初,我認為done
通道會以某種方式提前關閉或清理,但是即使done
是全局的,它也會導致相同的意外行為。
在done <- true
<-done
之前,不應該<-done
阻塞? 反之亦然?
似乎我期望程序在退出之前等待所有goroutine完成。 這是一個錯誤的假設。
這是一個骯臟的解決方法:
func main() {
done, reallydone := make(chan bool), make(chan bool)
println("enter")
defer func() {
<-reallydone
println("exit")
}()
go func() {
println(" wait start")
<-done
println(" wait end")
reallydone <- true
}()
defer func() {
println(" notify start")
done <- true
println(" notify end")
}()
time.Sleep(time.Millisecond)
}
當您使用sleep時,它將給goroutine啟動時間,然后在它從通道讀取時,主出口在調用最后一個println(" wait end")
之前退出。
但是,如果您不調用sleep,則defer將阻塞,直到goroutine從goroutine中讀取並為其提供了足夠的打印時間。
如果將代碼移到其他函數並從main調用,它將按預期工作。
func stuff() {
done := make(chan bool)
println("enter")
defer func() {
println("exit")
}()
go func() {
println(" wait start")
<-done
println(" wait end")
}()
defer func() {
println(" notify start")
done <- true
println(" notify end")
}()
}
func main() {
stuff()
}
done
通道上的事件序列:“ [通道未緩沖時,僅當發送方和接收方都准備就緒時,通信才成功”。 例如,
done
通道是未緩沖的: main
。
done := make(chan bool)
接收等待發送: go func()
。
<-done
接收就緒( <-done
),發送: defer func()
。
done <- true
main
函數結束,並且不等待goroutine( go func()
)完成。
輸出:
enter
wait start
notify start
notify end
exit
通道提供了一種機制,用於通過發送和接收指定元素類型的值來同時執行功能以進行通信。 未初始化通道的值為nil。
可以使用內置函數make創建新的初始化通道值,該函數將通道類型和可選容量作為參數:
make(chan int, 100)
容量(以元素數為單位)設置通道中緩沖區的大小。 如果容量為零或不存在,則通道是無緩沖的,並且僅在發送方和接收方都准備就緒時通信才能成功。 否則,如果緩沖區未滿(發送)或不為空(接收),則通道將被緩沖,並且通信將成功進行而不會阻塞。 零通道永遠不會准備好進行通信。
程序執行首先初始化主程序包,然后調用函數main。 當該函數調用返回時,程序退出。 它不等待其他(非主)goroutine完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.