我是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
}
但这似乎很不正确。有人可以给我一些想法吗?
非常感谢你的帮助。
答案 0 :(得分:9)
根据您的要求,您可能需要为每次迭代读取两个通道(即一种'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)
}
这永远运行。我首选的终止goroutine的方法是关闭输入通道。在这种情况下,您需要等待两者都关闭,然后在终止前等待close(out)
。
提示:请注意使用定向通道作为goroutine形式参数。编译器以这种方式编写时会遇到更多错误。快乐!
答案 1 :(得分:4)
最简单的答案是
func addnum(num1, num2, sum chan int) {
n1 := <- num1
n2 := <- num2
sum <- n1 + n2
}
由于您需要num1
和num2
来进行计算,否则进行计算是没有意义的。毕竟,有两种可能的执行顺序:
num1
生成一个数字,然后是num2
num2
生成一个数字,然后是num1
在第一种情况下,我们的通道读取完全对应于执行顺序。在第二种情况下,我们的第一次读取将阻止,直到num1
最终产生一个数字;第二次读取将近乎即时完成,因为num2
频道已有一个数字。
如果你想进一步了解Go中的频道,我建议你看一下http://godoc.org/github.com/thomas11/csp - 这是用Go编写的Hoare CSP示例的集合。
答案 2 :(得分:2)
回答“同时从多个频道阅读”的问题
有一种方法可以同时收听多个频道:
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。