进入例行程序,出现通道死锁

时间:2019-09-13 01:21:53

标签: go

我刚刚开始学习Go,所以请多多包涵,我尝试过Go的例程和频道,但是却以某种方式陷入僵局。

这是示例

package main

import (
    "fmt"
    "sync"
)


func main() {
    total := 2
    var wg sync.WaitGroup
    wg.Add(total)

    ch := make(chan int)

    for idx := 0; idx < total; idx++ {
        fmt.Printf("Processing idx %d\n", idx)

        go func(idx int) {
            defer wg.Done()
            ch <- idx
        }(idx)
    }

    for val := range ch {
        fmt.Println(val)
    }

    fmt.Println("Wait")
    wg.Wait()
}

会引发错误

Processing idx 0
Processing idx 1
1
0
fatal error: all goroutines are asleep - deadlock!

1 个答案:

答案 0 :(得分:2)

range ch从通道读取直到关闭。

您打几次close(ch)for val := range ch循环何时终止?


何时应该关闭频道?您在这里有很多选择,但是一种方法是添加另一个goroutine:

go func() {
    wg.Wait()
    close(ch)
}()

例如,在分解所有将先写到通道然后调用wg.Done()的例程之后,以便一旦所有写程序完成写操作,就关闭通道。 (您增加wg数量以考虑所有作者后,便可以运行此goroutine。)