下面这行代码为何为死锁

示例代码如下:

package main
import (
    "fmt"
    "sync"
)
func merge(cs ...<-chan int) <-chan int {
    var wg sync.WaitGroup
    out := make(chan int)

    // 为每一个输入channel cs 创建一个 goroutine output
    // output 将数据从 c 拷贝到 out,直到 c 关闭,然后 调用 wg.Done
    output := func(c <-chan int) {
        for n := range c {
            out <- n
        }
        wg.Done()
    }
    wg.Add(len(cs))
    for _, c := range cs {
        go output(c)
    }

    // 启动一个 goroutine,用于所有 output goroutine结束时,关闭 out
    // 该goroutine 必须在 wg.Add 之后启动
    go func() {
        wg.Wait()
        out <- 0
        close(out)
    }()
    return out
}

var ch1 chan int = make(chan int)
var ch2 chan int = make(chan int)
func fo(){
    for i := 0; i < 10; i++{
        if rand.Intn(2) == 0{
            ch1 <- 1
        }else{
            ch2 <- 2
        }
    }
}
func main(){
    go fo()
    for n := range merge(ch1, ch2){
        fmt.Println(n)
    }
}

不知为何会报all goroutines are asleep - deadlock!

阅读 1.8k
1 个回答

main 函数应该这样的

func main() {
    go func() {
        for n := range merge(ch1, ch2) {
            fmt.Println(n)
        }
    }()
    fo()
}

无缓冲的channel是阻塞的
当在向一个无缓冲的channel发送数据时,代码会阻塞直到有另一个goroutine接收这个channel
所以改进方法就是,先开启一个goroutine来接收

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