2 回答
TA贡献1725条经验 获得超7个赞
您的
Fibonacci
函数将 10 个值填充到通道中(它有 10 个值的缓冲区),然后关闭它。假设该v, ok <- chnvar
语句在主 goroutine 从通道中读取所有内容之前执行(很可能,但不能保证),将有一个值要读取,所以ok
将是真的。如果删除
close
调用,for
主 goroutine 中的循环最终将清空通道的缓冲区并阻塞等待更多数据。由于没有其他活跃的 goroutine 可以写入通道,运行时会将其检测为死锁。您的示例程序
Fibonacci
直接调用(而不是作为 goroutine)运行,因为它写入的通道是缓冲的,并且它永远不会溢出缓冲区。因此,它可以在不阻塞的情况下完成,并允许继续执行main
函数的其余部分。如果通道没有被缓冲,或者你写的值超过了缓冲区的容量,那么
Fibonacci
会阻塞等待其他 goroutine 从通道读取一些东西。
TA贡献1843条经验 获得超7个赞
1)
Go 规范说明了通道接收操作(我的重点):
x, 好的 := <-ch
如果接收到的值是通过成功的发送操作传递到通道,则 ok 的值为 true,如果由于通道关闭且为空而生成的零值,则值为 false 。
也就是说,因为缓冲的通道不为空并且您已成功接收到值 (0),所以ok
为真。在通道清空之前,您不会收到 false。
2)
通过运行Fibonacci(cap(chn), chn)
它自己的 Go 例程,main 可以开始接收和处理(打印)输出值,同时 Fibonacci 函数仍在向通道提供新值。
在您的情况下,这可能永远不会发生,因为该函数将填满缓冲区并在 main 有机会处理任何内容之前完成。
如果它不会在 Go 例程中运行,Fibonacci 将首先需要生成所有值,然后它们才能被 main 进一步处理。
- 2 回答
- 0 关注
- 200 浏览
添加回答
举报