在Golang中同时从多个频道读取

Jin*_*ing 9 concurrency go channels

我是Golang的新手.现在我想弄清楚如何在Golang中建立一对一的通道,其设置如下:

说我有两个goroutine numgen1和numgen2同时执行并将数字写入通道num1 resp.NUM2.我想在新进程addnum中添加从numgen1和numgen2发送的数字.我尝试过这样的事情:

func addnum(num1, num2, sum chan int) {
    done := make(chan bool)
    go func() {
        n1 := <- num1
        done <- true
    }()
        n2 := <- num2
        <- done
    sum <- n1 + n2
}
Run Code Online (Sandbox Code Playgroud)

但这似乎很不正确.有人可以给我一些想法吗?

非常感谢您的帮助.

Ric*_*777 11

根据您的要求,您可能需要为每次迭代读取两个通道(即一种'zip'功能).您可以使用select执行此操作,类似于user860302的答案:

func main() {

  c1 := make(chan int)
  c2 := make(chan int)
  out := make(chan int)

  go func(in1, in2 <-chan int, out chan<- int) {
    for {
      sum := 0
      select {
      case sum = <-in1:
        sum += <-in2

      case sum = <-in2:
        sum += <-in1
      }
      out <- sum
    }
  }(c1, c2, out)
}
Run Code Online (Sandbox Code Playgroud)

这永远运行.我首选的终止goroutine的方法是关闭输入通道.在这种情况下,您需要等待两者都关闭,然后close(out)才能终止.

提示:请注意使用定向通道作为goroutine形式参数.编译器以这种方式编写时会遇到更多错误.幸福!


pub*_*her 5

最简单的答案是

func addnum(num1, num2, sum chan int) {
  n1 := <- num1
  n2 := <- num2
  sum <- n1 + n2
}
Run Code Online (Sandbox Code Playgroud)

由于您需要num1num2进行计算,否则这样做是没有意义的。毕竟,有两种可能的执行顺序:

  1. num1 生成一个数字,然后是 num2
  2. num2 生成一个数字,然后是 num1

在第一种情况下,我们的通道读取完全对应于执行顺序。在第二种情况下,我们的第一次读取将阻塞,直到num1最终产生一个数字;第二次读取将几乎瞬时完成,因为num2通道已经有了一个数字。

如果您想了解有关 Go 中通道的更多信息,我建议您查看http://godoc.org/github.com/thomas11/csp——这是 Hoare 用 Go 编写的 CSP 示例的集合。