通道和等待组进入死锁

我在争论 goroutine 并让他们与主要 goroutine 上的频道进行交流时遇到了麻烦。为简化起见,我的代码如下所示:



func main() {

    channel := make(chan string)

    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {

        wg.Add(1)

        go performTest(channel, &wg, i)

    }


    wg.Wait()

    close(channel)


    for line := range channel {

        fmt.Print(line)

    }

}


func performTest(channel chan string, wg *sync.WaitGroup, i int) {

     defer wg.Done()

     // perform some work here

     result := fmt.sprintf("Pretend result %d", i)

     channel <- result

}

这似乎进入了某种僵局,但我不明白为什么。它卡住了wg.Wait(),即使我希望它在所有 goroutine 都调用Done等待组后继续。我在这里想念什么?我想等待 goroutines,然后遍历通道中的所有结果。


千万里不及你
浏览 92回答 1
1回答

收到一只叮咚

您可以等待组并在单独的 go 例程中关闭通道。如果通道关闭,您在通道上的范围将在收到最后一个发送的值后结束。如果您只是等待,则不会从频道收到任何内容。由于通道是无缓冲的,performTestgoroutines 将无法发送。对于无缓冲通道,发送操作将阻塞,直到它被接收。因此,延迟wg.Done调用永远不会发生,您的程序就会陷入僵局。由于Done仅在执行永久阻塞发送后调用。func main() {&nbsp; &nbsp; channel := make(chan string)&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go performTest(channel, &wg, i)&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // this is the trick&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(channel)&nbsp; &nbsp; }()&nbsp; &nbsp; for line := range channel {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Print(line)&nbsp; &nbsp; }}func performTest(channel chan string, wg *sync.WaitGroup, i int) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; // perform some work here&nbsp; &nbsp; result := fmt.Sprintf("Pretend result %d\n", i)&nbsp; &nbsp; channel <- result}https://play.golang.com/p/5pACJzwL4Hi
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go