缓冲通道关闭TRUE?

时间:2013-12-18 21:12:53

标签: concurrency go buffer channel

我在缓冲频道上有一些问题

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)
}

非常感谢!

2 个答案:

答案 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的答案可能更有用。你的程序做了很多不正确的事情,虽然很有趣。