4

我在 go 中遇到了一个死锁问题。

该程序接受一个整数数组 a,并将其分成两部分。然后它将这两个部分放在两个不同的例程中并总结所有元素。在此之后,它应该在通道 res 中发送两个结果。然后应该将两个 res(现在是 ch)加在一起并打印。

我的问题:我试图通过大量移动关闭函数来解决死锁问题,但似乎没有任何帮助。显然,它只适用于一个例程 Add 运行。

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)
}
4

1 回答 1

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)
}

演示: http ://play.golang.org/p/oHcrUStjmm

于 2013-03-19T23:51:02.610 回答