我正在经历Go Tour,这段代码真的融化了我的思想:package mainimport "fmt"func fibonacci(c, quit chan int) { x, y := 0, 1 for { select { case c <- x: x, y = y, x+y case <-quit: fmt.Println("quit") return } }}func main() { c := make(chan int) quit := make(chan int) go func() { for i := 0; i < 5; i++ { fmt.Println(<-c) } // quit <- 0 // Suppose I remove this line (note that it is present in the Tour) }() fibonacci(c, quit)}现在我得到一个致命的错误,告诉我所有的goroutine都处于睡眠状态,所以我假设开放通道阻止程序返回和退出。问题是,为什么这会导致错误?程序结束了,通道有读取器,并且没有更多的代码语句要执行,那么这里到底发生了什么呢?cP.S 如果通道从未评估为 True,这是否意味着第一个情况将永远循环?quit
1 回答
慕哥6287543
TA贡献1831条经验 获得超10个赞
tl;博士
由于您从未向频道写入任何内容,因此您的程序会在选择案例语句上死锁,您的程序会不断生成值并将其添加到没有使用者的频道中。quitc
解释
代码正在等待将某些内容添加到通道中。由于它没有被写入,程序继续计算斐波那契数列。quit
并发编程与“标准”线性规划非常不同。
您删除的行将保证通道中有足够的数据来结束节目,因为该函数仅在从中读取该通道时结束。quitfib
for { // an infinite loop
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return // your only exit is here,
// which is only executed when data is read from the quit channel
}
您永远在计算值,您唯一的退出是写入通道;但是,这永远不会发生。quit
- 1 回答
- 0 关注
- 145 浏览
添加回答
举报
0/150
提交
取消
