for循环导致死锁

时间:2017-02-09 22:58:00

标签: go concurrency

我已经从GO Concurrency编写了一些代码示例:

func gen(numbers ...int) <-chan int {
    out := make(chan int)

    go func() {
        for _, number := range numbers {
            out <- number
        }
        close(out)
    }()

    return out
}

func sq(in <-chan int) <-chan int {
    out := make(chan int)

    go func() {
        for number := range in {
            out <- number * number
        }
    }()

    return out
}

所以我尝试在我的主函数中使用上面的代码:

func main() {



    result := sq(sq(sq(gen(1, 2, 3, 4))))

    fmt.Println(<-result)
    fmt.Println(<-result)
    fmt.Println(<-result)
    fmt.Println(<-result)

    fmt.Println("-------------------")

    for channelValue := range sq(sq(sq(gen(1, 2, 3, 4)))) {
        fmt.Println(channelValue)
    }

}

当我运行代码时,我感到很困惑,我在循环之后得到了这条消息:

  

致命错误:所有goroutine都睡着了 - 死锁

请帮我理解这一点。据我所知,调用fmt.Prinlnt(result) x 4次与for channelValue := range sq(sq(sq(gen(1, 2, 3, 4))))上的for循环相同。这是对的吗?

请告诉我为什么循环后我遇到了死锁?

2 个答案:

答案 0 :(得分:2)

通道阻止的范围,因为通道没有以sq。

关闭
class

调试这样的死锁的好方法是向进程发送SIGQUIT。收到SIGQUIT时,运行时会转储所有goroutine的堆栈。堆栈转储通常会指出问题。

答案 1 :(得分:1)

您未关闭setTimeout功能中的out频道

sq

https://play.golang.org/p/kk8-08SfwB