[英]Closing channels in Go
我正在學習頻道在Go中的工作方式,偶然發現了關閉頻道的問題。 這是A Tour of Go中的一個修改示例, 該示例生成n-1個斐波那契數並通過通道發送它們,而未使用通道容量的最后一個“元素”。
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n-1; i++ {
c <- x
x, y = y, x+y
}
// close(c) // It's commented out on purpose
}
func main() {
n := 10
c := make(chan int, n)
go fibonacci(n, c)
for i := 0; i < n; i++ {
_, ok := <-c
fmt.Println(ok)
}
}
問題是我得到:
致命錯誤:所有goroutine都在睡着-死鎖!
當我不關閉通道時。 到底是什么造成了僵局? 當我不關閉通道時,為什么不能在其容量范圍內接收到該通道?
您正在將n個值寫入通道(從0到n-1 ),但是試圖從通道中讀取n + 1個值(從0到n )。 在不顯式關閉通道的情況下, main
函數將永遠等待最后一個值。
到底是什么造成了僵局?
經過n次迭代后,運行fibonacci
函數的goroutine將退出。 此goroutine退出后,程序中唯一剩下的goroutine是main
goroutine,並且該goroutine正在等待將某些數據寫入c
通道-並且由於沒有其他goroutine可能會向其中寫入數據頻道,它將永遠等待。 這正是錯誤消息試圖告訴您的內容: “所有goroutines (這里的“ all”都只是一個”) 在睡着了” 。
main
函數中的_, ok := <- c
調用只會在關閉c
通道后立即停止阻塞(由於從通道讀取正在阻塞,因此需要從另一個goroutine完成)。 當通道關閉時, main
函數將從通道中讀取剩余數據(當它是緩沖通道時)
對於主循環,期望在通道中進行n次通信,但在功能斐波那契中僅產生n-1次
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ { //here
c <- x
x, y = y, x+y
}
// close(c) // It's commented out on purpose
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.