具有多个通道的多个goroutine的死锁

时间:2018-11-05 05:11:31

标签: go channel goroutine

我正在研究一个示例程序,以使用具有多个通道的goroutine打印1至100之间的奇数和偶数和。

您可以找到我的代码

here

输出

req = http.post<MyResponse>(url, [{...}])
  .subscribe(
    res => {
    console.log(res);
    var resp = res.Results[0].results.map(x => {
    return {id: x.ID, severity: x.CVSS, cve_link: x.link };
    } );

该代码有效,但存在死锁。 我不确定我的代码有什么问题

1 个答案:

答案 0 :(得分:2)

我们可以迭代通过通道发送的值。为了打破这种迭代通道,需要明确关闭。否则,范围将永远与无通道相同地被阻塞。在您的代码中,您没有关闭sum(用于打印功能sumValues通道)通道。这就是为什么跟踪功能将永远被阻止的原因。

func print(sumValues <-chan string ){
    for val := range sumValues {
        fmt.Println(val)
    }
}

因此,您必须在sum函数中的所有go例程完成之后关闭doSum函数中的doSum通道(否则,在关闭sum通道之前, go例程已完成)。您可以使用sync.WaitGroup来做到这一点。请参见下面更新的doSum函数:

func doSum(sum chan<- string, oddChan <-chan int, evenChan <-chan int) {
    var waitGroup sync.WaitGroup

    waitGroup.Add(2) // Must wait for 2 calls to 'done' before moving on

    go func(sum chan<- string) {
        s1 := 0
        for val := range oddChan {
            s1 += val
        }
        sum <- fmt.Sprint("sum of odd number = ", s1)
        waitGroup.Done()
    }(sum)

    go func(sum chan<- string) {
        s1 := 0
        for val := range evenChan {
            s1 += val
        }
        sum <- fmt.Sprint("sum of even number = ", s1)
        waitGroup.Done()
    }(sum)

    // Waiting for all goroutines to exit
    waitGroup.Wait()

    // all goroutines are complete now close the sum channel
    close(sum)
}
相关问题