【问题标题】:How can I transfer a value from one Go channel to another without an implicit buffer?如何在没有隐式缓冲区的情况下将值从一个 Go 通道传输到另一个通道?
【发布时间】:2018-12-25 22:58:09
【问题描述】:

假设我有一个从一个通道读取并写入另一个通道的 goroutine。

ch1 := make(chan int)
ch2 := make(chan int)
go func() {
  for num := range ch1 {
    ch2 <- num+1
  }
}()

如果 ch2 被阻塞,goroutine 仍然会从 ch1 读取一个值,有效地在通道中引入一个 1 的缓冲区。由于我使用通道进行控制流,因此我不需要任何缓冲。

如何制作一个以完全锁步方式执行的管道? 或者换句话说,如何在一个原子操作中将值从一个通道传输到下一个通道?

我基本上想等待ch1ch2 到达集合点。

【问题讨论】:

    标签: go pipeline channel


    【解决方案1】:

    您不能使用 2 个频道来执行此操作。为了在ch2 上执行发送,要发送的值必须已经准备好、已评估。 Spec: Send statements:

    通道和值表达式都在通信开始之前进行评估。

    因此,即使您这样做,它似乎也不会缓冲任何变量中的值:

    ch2 <- (<- ch1)
    

    不过,来自ch1 的接收将首先被评估,然后才会尝试发送。

    这意味着该值必须已经从ch1 收到。但是,如果不尝试在 ch2 上发送,您就无法判断是否有人在 ch2 上“收听”(这意味着是否可以继续在 ch2 上发送)(即使可以,也不能保证尝试检查后发送仍然会有人在听它)。

    【讨论】:

    • 就像一个注释:Rob Pike proposed 在 Go 2 中添加一个 splice 到频道,这似乎只是为了解决这个问题。
    • 原来的拼接提案并没有真正涵盖我想要的,但是github.com/golang/go/issues/26282#issuecomment-405786296这正是我上面描述的。除了我不确定他所说的如何重构代码是什么意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2018-04-15
    • 2019-01-07
    • 1970-01-01
    • 2016-06-06
    • 2016-06-28
    • 1970-01-01
    相关资源
    最近更新 更多