猿问

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

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

你可以找到我的代码

这里

输出

sum of even number = 2550

sum of odd number = 2500

fatal error: all goroutines are asleep - deadlock!


goroutine 1 [chan receive]:

main.print(0x434100, 0x11db7c)

    /tmp/sandbox052575152/main.go:18 +0xc0

main.main()

    /tmp/sandbox052575152/main.go:14 +0x120

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


翻阅古今
浏览 75回答 1
1回答

撒科打诨

我们可以遍历通过通道发送的值。要打破这种迭代通道,需要明确关闭。否则 range 将以与 nil 通道相同的方式永远阻塞。在您的代码中,您没有关闭sum(打印功能sumValues通道)通道。这就是为什么以下功能将永远被阻止的原因。func print(sumValues <-chan string ){&nbsp; &nbsp; for val := range sumValues {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(val)&nbsp; &nbsp; }}所以你必须在函数sum中的doSum所有 go 例程doSum完成后关闭函数中的通道(否则sum通道可能会在 go 例程完成之前关闭)。你可以用sync.WaitGroup它来做到这一点。请参阅下面的更新doSum功能:func doSum(sum chan<- string, oddChan <-chan int, evenChan <-chan int) {&nbsp; &nbsp; var waitGroup sync.WaitGroup&nbsp; &nbsp; waitGroup.Add(2) // Must wait for 2 calls to 'done' before moving on&nbsp; &nbsp; go func(sum chan<- string) {&nbsp; &nbsp; &nbsp; &nbsp; s1 := 0&nbsp; &nbsp; &nbsp; &nbsp; for val := range oddChan {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s1 += val&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; sum <- fmt.Sprint("sum of odd number = ", s1)&nbsp; &nbsp; &nbsp; &nbsp; waitGroup.Done()&nbsp; &nbsp; }(sum)&nbsp; &nbsp; go func(sum chan<- string) {&nbsp; &nbsp; &nbsp; &nbsp; s1 := 0&nbsp; &nbsp; &nbsp; &nbsp; for val := range evenChan {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s1 += val&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; sum <- fmt.Sprint("sum of even number = ", s1)&nbsp; &nbsp; &nbsp; &nbsp; waitGroup.Done()&nbsp; &nbsp; }(sum)&nbsp; &nbsp; // Waiting for all goroutines to exit&nbsp; &nbsp; waitGroup.Wait()&nbsp; &nbsp; // all goroutines are complete now close the sum channel&nbsp; &nbsp; close(sum)}
随时随地看视频慕课网APP

相关分类

Go
我要回答