我在go中遇到了一个死锁问题。
该程序采用一系列整数,a,并将其分为两部分。然后,它将这两个部分分为两个不同的例程,并总结所有元素。在此之后,它应该在通道res中发送两个结果。然后应将两个res(现在为ch)加在一起并打印。
我的问题:我试图通过移动关闭功能来解决死锁问题,但似乎没有任何帮助。它只适用于一个例程添加运行。
package main
import (
"fmt"
)
// Add adds the numbers in a and sends the result on res.
func Add(a []int, res chan<- int) {
sum := 0
for i := range a {
sum = sum + a[i]
}
res <- sum
}
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7}
n := len(a)
ch := make(chan int)
go Add(a[:n/2], ch)
go Add(a[n/2:], ch)
sum := 0
for s := range ch {
sum = sum + s
}
//close(ch)
fmt.Println(sum)
}
答案 0 :(得分:4)
您永远不会关闭频道,因此range
无法退出。它会继续尝试接收,但没有任何东西可以发送。
你需要为你的Add()
函数找到一些方法,看看它是什么时候结束,如果它是最后一个,那么它可以close()
通道,或者你可以只减少一个计数器在循环中使用range
,这样就不需要使用close()
。
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7}
n := len(a)
ch := make(chan int)
go Add(a[:n/2], ch)
go Add(a[n/2:], ch)
sum := 0
// counts the number of messages sent on the channel
count := 0
// run the loop while the count is less than the total number of routines
for count < 2 {
s := <-ch
sum = sum + s
count++ // Increment the count after a routine sends its value
}
fmt.Println(sum)
}