猿问

缓冲通道关闭 TRUE?

我有一些问题...关于缓冲频道


一季度。


那为什么 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)

}

非常感谢!


慕尼黑5688855
浏览 211回答 2
2回答

喵喔喔

Q1:你从来没有value, ok <- ch在一个未关闭的通道上做:在 NB 中你在 closed 之后执行这个语句ch,而在 main 中你在 for 循环中从 ch 读取所有内容后执行它。为什么您希望返回ok==true以表明通道未关闭?Q2:一旦从主NB中的ch消耗了3,可能会在主开始打印之前再次运行并打印。NB 和 main 之间绝对没有同步。再说一遍:你对这样的代码有什么期望?如果您想模拟斐波那契数列的生成器,则不应从 ch 中读取 NB。这与缓冲无关。缓冲通道只是允许一些 goroutine 在阻塞通道发送之前执行更长时间。

杨魅力

这与通道关闭操作的工作方式有关。输出中最有趣的部分是,对于缓冲的 NB ok(非 MAIN 版本)是true,但 VB 值仍然为 0。它返回 0 因为它已关闭,但由于尚未读取所有值,它没有耗尽(所有发送的值都已收到)。我不确定为什么输出顺序不同 - 我认为这是不确定的。但是,@Volker 的答案可能是更有用的答案。你的程序做错了很多事情,尽管很有趣。
随时随地看视频慕课网APP

相关分类

Go
我要回答