goroutines之间的僵局

时间:2017-04-08 16:22:46

标签: go goroutine

我是Go的新手。当我评论第二个goroutine时,有一个致命的错误。我不明白导致此错误的原因。你能解释一下吗?

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    go func() { 
        for i := 0; i < 10; i++ {
            ch <- i
        }
    } ()
    // go func() { 
        for {
            if num, ok := <-ch; !ok {
                break
            } else {
                fmt.Printf("%d\n", num)
            }
        }
    // } ()
    time.Sleep(2 * time.Second)
    close(ch)
}

这将打印以下代码:

0
1
2
3
4
5
6
7
8
9
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    /tmp/sandbox169127128/main.go:17 +0xa0

Program exited.

2 个答案:

答案 0 :(得分:5)

接收来自发送goroutine的所有值后从ch接收的循环块。运行时检测到程序卡住并发生恐慌。

修复是在发送所有值后关闭频道:

go func() { 
    for i := 0; i < 10; i++ {
        ch <- i
    }
    close(ch)
} ()

在封闭频道上接收会产生值0, false。 receive for循环中断了false值。

从程序末尾删除close(ch)

Run it on the playground

答案 1 :(得分:2)

因为在第一个goroutine退出之前你没有关闭频道。以下代码应该有效。

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    go func() { 
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    } ()
    //go func() { 
        for {
            if num, ok := <-ch; !ok {
                break
            } else {
                fmt.Printf("%d\n", num)
            }
        }
    //} ()
    time.Sleep(2 * time.Second)
}

在此处试试:https://play.golang.org/p/OdxNqbaZmj