【问题标题】:Why are all goroutines asleep?为什么所有的 goroutine 都处于休眠状态?
【发布时间】:2019-07-26 15:21:39
【问题描述】:

以下是代码;

package main

import "fmt"

func main() {
    func1(1)
}

func func1(n int) {
    ch := make(chan int)
    ch <- 1
        for i := range ch {
            fmt.Println(i)
            fmt.Println(<-ch)
        }   
}

当我尝试执行这段代码时,它会抛出以下错误;

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.func1(0x1, 0x432070)
    /tmp/sandbox451742015/main.go:11 +0x60
main.main()
    /tmp/sandbox451742015/main.go:6 +0x20

【问题讨论】:

标签: go concurrency deadlock channel goroutine


【解决方案1】:

您的频道是无缓冲的,因此在它上的第一次发送将被阻塞,直到有人从它接收。但是从它那里收到的代码是在那之后,所以这是一个“立即”的死锁。

你可以像ch := make(chan int, 1) 那样让它没有缓冲,所以发送不会阻塞,但是你有一个单一的goroutine,它在一个通道上有一个for range。此循环仅在通道关闭时退出,但您永远不会关闭它。而且您只在其上发送一个值,因此循环被阻塞,等待它可以接收的值或关闭通道。

你需要另一个 goroutine 来关闭通道。在循环内部,您不需要再次从通道接收,循环结构已经这样做了。 i 将是从通道接收到的值。

有意义的工作示例:

func func1(n int) {
    ch := make(chan int)
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch)
    }()
    for i := range ch {
        fmt.Println(i)
    }
}

这个输出(在Go Playground上试试):

0
1
2
3
4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-22
    • 2012-09-06
    • 2015-04-25
    • 2021-04-05
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    • 2017-05-29
    相关资源
    最近更新 更多