为什么会这段代码出现fatal error: all goroutines are asleep - deadlock!

func main() {

A := make(chan bool)
B := make(chan bool)
defer close(A)
defer close(B)
var wg sync.WaitGroup
wg.Add(2)
go func() {
    for i := 0; i < 10; i += 2 {
        if <-A {
            fmt.Println(i)
            B <- true
        }
    }
    wg.Done()
}()
go func() {
    for i := 1; i < 10; i += 2 {
        if <-B {
            fmt.Println(i)
            A <- true
        }
    }
    wg.Done()
}()
A <- true
wg.Wait()

}

阅读 2.5k
2 个回答

看code,应该是用waitgroup来做收尾工作,两个goroutine交替执行。
问题出在B routine的最后一次写入A <- true,这个时候从A channel读入数据的code已经没有机会执行了,所以程序hang在那里了

加一个简单的读入,就可以顺利执行了


func main() {
    A := make(chan bool)
    B := make(chan bool)
    defer close(A)
    defer close(B)
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
        for i := 0; i < 10; i += 2 {
            if <-A {
                fmt.Println(i)
                B <- true
            }
        }
        <-A
        wg.Done()
    }()
    go func() {
        for i := 1; i < 10; i += 2 {
            if <-B {
                fmt.Println(i)
                A <- true
            }
        }
        wg.Done()
    }()
    A <- true
    wg.Wait()
}

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

新手上路,请多包涵

第二个 goroutine 最后一轮循环的 A <- true 没有地方接收,阻塞了。

func main() {
    A := make(chan bool)
    B := make(chan bool)
    endch := make(chan struct{})
    defer close(A)
    defer close(B)
    defer close(endch)
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
        for i := 0; i < 10; i += 2 {
            if <-A {
                fmt.Println(i)
                B <- true
            }
        }
        wg.Done()

        endch <- struct{}{}
    }()

    go func() {
        for i := 1; i < 10; i += 2 {
            if <-B {
                fmt.Println(i)
                A <- true
            }
        }
        wg.Done()
    }()

    A <- true
    <-endch
    <-A
    wg.Wait()
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题