等待组。等待() 导致死锁

我试图弄清楚为什么我有一个带有等待组的死锁。等待()


package main


import (

    "fmt"

    "sync"

)


var wg sync.WaitGroup


func foo(c chan int, i int) {

    defer wg.Done()

    c <- i

}


func main() {

    ch := make(chan int)

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

        wg.Add(1)

        go foo(ch, i)

    }

    wg.Wait()

    close(ch)

    for item := range ch {

        fmt.Println(item)

    }

}

当我像这样运行它时,它会打印fatal error: all goroutines are asleep - deadlock!


我试图更改为缓冲通道,这解决了问题。但我真的很想知道为什么会有死锁。ch


胡子哥哥
浏览 62回答 1
1回答

慕码人8056858

我已经注释掉了程序逻辑不正确的部分:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")var wg sync.WaitGroupfunc foo(c chan int, i int) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; c <- i}func main() {&nbsp; &nbsp; ch := make(chan int) // unbuffered channel&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go foo(ch, i)&nbsp; &nbsp; }&nbsp; &nbsp; // wg.Wait is waiting for all goroutines to finish but that's&nbsp; &nbsp; // only possible if the send to channel succeeds. In this case,&nbsp; &nbsp; // it is not possible as your receiver "for item := range ch" is below&nbsp; &nbsp; // this. Hence, a deadlock.&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; // Ideally, it should be the sender's duty to close the channel.&nbsp; &nbsp; // And closing a channel before the receiver where the channel&nbsp; &nbsp; // is unbuffered is not correct.&nbsp; &nbsp; close(ch)&nbsp; &nbsp; for item := range ch {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(item)&nbsp; &nbsp; }}更正的程序:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")var wg sync.WaitGroupfunc foo(c chan int, i int) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; c <- i}func main() {&nbsp; &nbsp; ch := make(chan int)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for item := range ch {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(item)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go foo(ch, i)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; close(ch)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go