此示例取自http://blog.golang.org/pipelines。它运行并给出正确答案,但它显示以下运行时错误:"致命错误:所有goroutine都处于睡眠状态 - 死锁!"。任何人都可以帮助我理解为什么会这样吗? 包主要
import (
"fmt"
)
func gen(nums ...int) <- chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
}()
return out
}
func sq(in <- chan int) <- chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}
func main() {
for n := range sq(gen(2,3)) {
fmt.Println(n)
}
}
然而,以下修改并不是。
func main() {
// Set up the pipeline.
c := gen(2, 3)
out := sq(c)
// Consume the output.
fmt.Println(<-out) // 4
fmt.Println(<-out) // 9
}
答案 0 :(得分:2)
for n := range in
函数的sq()
永不退出,并开始阻止(读取2个值后),因为gen()
从未关闭其频道。
将close(out)
添加到go func
的{{1}}会使其有效:see playground。
通过通道,接收器将阻塞,直到收到值 The range keyword, when used with a channel, will wait on the channel until it is closed。
gen()
被屏蔽,这意味着sq()
永远不会被调用,反过来close(out)
会阻止main()
(因为频道range sq()
不是sq
关闭)。
在您的第二个示例中,main()
本身会退出,这意味着即使sq()
被阻止,一切仍然会停止。