go - goroutines之间的死锁

标签 go goroutine

我是 Go 的新手。当我注释掉第二个 goroutine 时,出现 fatal error 。我不明白是什么原因导致此错误发生。你能给我解释一下吗?

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.

最佳答案

在从发送 goroutine 接收到所有值后,接收 for 循环会阻塞从 ch 接收。运行时检测到程序卡住并panic。

解决方法是在发送所有值后关闭 channel :

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

在关闭的 channel 上接收产生值 0,false。接收 for 循环在 false 值处中断。

从程序末尾删除 close(ch)

Run it on the playground .

关于go - goroutines之间的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43297474/

相关文章:

Go 项目结构 - 最佳实践

php - 在PHP openssl_encrypt和golang河豚中匹配河豚加密

go - 我可以在 go 中使用 make(chan someStruct) 吗?

go - 如果我知道 golang channel 的所有值是有限的,我是否应该消耗它们?

go - 我如何使用 channel 来知道循环启动的所有 goroutines 何时完成

go - Go中嵌套结构的问题

go - golang的websocket服务端如何主动向客户端发送消息

reflection - 是否可以在 go 中动态创建带有接收器(方法)的函数?

Go goroutine 泄漏

几分钟后,Go 爬虫在从输出 channel 中选择时停止