16

我是 Golang 的新手。现在我正在尝试弄清楚如何在 Golang 中创建一个任意一对一的频道,其中设置如下:

假设我有两个 goroutine numgen1 和 numgen2 同时执行并将数字分别写入通道 num1。编号2。我想在一个新进程 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
}

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

非常感谢您的帮助。

4

3 回答 3

16

根据您的要求,您可能需要在每次迭代时读取两个通道(即一种“zip”功能)。您可以通过选择来执行此操作,类似于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)
}

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

提示:注意使用定向通道作为 goroutine 形式参数。当您以这种方式编写时,编译器会捕获更多错误。幸福!

于 2013-12-16T09:43:28.280 回答
8

最简单的答案是

func addnum(num1, num2, sum chan int) {
  n1 := <- num1
  n2 := <- num2
  sum <- n1 + n2
}

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

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

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

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

于 2013-12-15T09:47:30.610 回答
4

回答“同时从多个渠道读取”的问题

有一种方法可以同时收听多个频道:

func main() {

    c1 := make(chan string)
    c2 := make(chan string)

    ...
    go func() {
        for {
            select {
                case msg1 := <- c1:
                fmt.Println(msg1)

                case msg2 := <- c2:
                fmt.Println(msg2)
             }
        }
    }()

在本例中,我创建了一个通道 msg1 和 msg2。然后我创建一个带有无限循环的 go 例程。在这个循环中,我听 msg1 AND msg2。该系统允许您同时读取多个通道并在到达时处理消息。

为了避免泄漏,我可能应该添加另一个通道来停止 goroutine。

于 2013-12-16T00:19:08.733 回答