Go中的死锁,两个例程分裂工作

时间:2013-03-19 23:35:38

标签: go deadlock goroutine channels

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

1 个答案:

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

DEMO: http://play.golang.org/p/oHcrUStjmm