我在缓冲频道上有一些问题
Q1。
那么为什么NonBuffered从不输出TRUE值?
这是否意味着无缓冲通道始终关闭? 那么为什么无缓冲通道仍能产生斐波纳契计算的正确结果呢?
Q2。
为什么NonBuffered输出会像下面那样在中间被切断?
0 1 1 2 NB value: 0
NB ok: false
3
它应该与goroutine有关但是为什么这样呢?
很难理解,因为如果我缓冲这个频道,我会得到真正的价值,但是使用无缓冲的频道,我只能得到假...
请查看以下链接。
http://play.golang.org/p/O2Th61DfEY
package main
import "fmt"
func main() {
ch := make(chan int)
go NB(5, ch)
for i := range ch {
fmt.Printf("%d ", i)
}
/*
0 1 1 2 NON_Buffered value: 0
NON_Buffered ok: false
3
*/
fmt.Println()
value, ok := <-ch
fmt.Println("MAIN = NB value:", value)
fmt.Println("MAIN = NB ok:", ok)
}
func NB(n int, ch chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
ch <- x
x, y = y, x+y
}
close(ch)
value, ok := <-ch
fmt.Println("NB value:", value)
fmt.Println("NB ok:", ok)
}
非常感谢!
答案 0 :(得分:1)
Q1:你永远不会在未关闭的通道上执行value, ok <- ch
:在NB中你在关闭ch
后执行这个语句,而在main中你在for循环中读取ch之后执行它。为什么期望返回ok==true
以表明频道未关闭?
Q2:从主要NB中的ch消耗3后,可以再次运行并在主要开始打印之前打印。 NB和main之间绝对没有同步。再说一遍:你对这些代码有什么期望?
如果你想为斐波那契数字模拟一个生成器,那你应该从 读取NB中的NB。这与缓冲无关。缓冲通道只允许某些goroutine在阻止通道发送之前执行更长时间。
答案 1 :(得分:0)
这是channel Close操作的工作原理。输出中最有趣的部分是,对于缓冲,NB ok(非MAIN版本)是true
,但VB值仍为0.它返回0因为它已关闭,但由于所有值都没有还没有读过,它没有耗尽(所有发送的值都已收到)。我不确定为什么输出顺序不同 - 我认为这是不确定的。
但是,@ Volker的答案可能更有用。你的程序做了很多不正确的事情,虽然很有趣。