【问题标题】:Buffered channel close TRUE?缓冲通道关闭 TRUE?
【发布时间】:2014-01-07 05:49:48
【问题描述】:

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

第一季度。

那为什么 NonBuffered 从不输出 TRUE 值呢?

这是否意味着无缓冲通道总是关闭? 那么为什么无缓冲通道仍然会产生正确的斐波那契计算结果呢?


第二季度。

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

非常感谢!

【问题讨论】:

    标签: concurrency go buffer channel


    【解决方案1】:

    Q1:您永远不会在未关闭的通道上执行 value, ok &lt;- ch:在 NB 中,您在关闭 ch 后执行此语句,而在 main 中,您在 for 循环中从 ch 读取所有内容后执行它。为什么您期望返回ok==true 以表明频道未关闭?

    Q2:一旦从主 NB 中的 ch 消耗了 3,可能会在主开始打印之前再次运行并打印。您在 NB 和 main 之间绝对没有同步。再说一遍:你对这样的代码有什么期望?

    如果你想模拟斐波那契数的生成器,你应该从 ch.这与缓冲无关。缓冲通道只是允许一些 goroutine 在阻塞通道发送之前执行更长时间。

    【讨论】:

    • play.golang.org/p/CvQjOVaYxx 我希望这是真的,或者想知道为什么它与缓冲的不同。
    • 也许我现在就继续这个,因为我可以使用缓冲通道进行正确的输出。非常感谢!
    【解决方案2】:

    这是channel Close 操作的工作原理。输出中最有趣的部分是,对于缓冲,NB ok(非 MAIN 版本)是true,但 VB 值仍然是 0。它返回 0 因为它已关闭,但由于所有值都没有尚未读取,它没有耗尽(已收到所有发送的值)。我不确定为什么输出顺序不同 - 我认为这是不确定的。

    不过,@Volker 的回答可能更有用。你的程序做错了很多事情,尽管很有趣。

    【讨论】:

    • 是的,这段代码很糟糕。我可以只使用缓冲的。非常感谢!
    猜你喜欢
    • 2018-12-01
    • 2016-06-20
    • 2014-01-30
    • 1970-01-01
    • 2012-01-15
    • 2021-10-13
    • 2017-09-06
    • 2016-08-30
    • 1970-01-01
    相关资源
    最近更新 更多