美文网首页
干货 all goroutines are asleep - d

干货 all goroutines are asleep - d

作者: lucasgao | 来源:发表于2019-07-10 00:28 被阅读0次

    我们学习通道channel的时候,偶尔会在测试的时候遇到 all goroutines are asleep这样的panic错误,但是这个是怎么造成的呢。本文首先会介绍产生这个的原因,然后会结合具体案例进行详细分析。

    错误原因

    这个错误其实已经写的比较明白了,所有的 协程(goroutines)都处于休眠(阻塞)状态。当所有协程都处于阻塞状态的时候,那所有的协程都等不来解锁的那一天了,出现死锁,所以golang调度直接把这个给kill掉了。
    简单来说出现这样的原因是主线程在阻塞,但是其他协程由于各种原因也阻塞了。

    下面分享几个学习中遇到的案例

    案例详解(持续更新)

    案例一

    代码如下:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func service1(ch chan string) {
        fmt.Println("BEEFORE")
        ch <- "from service1"
        fmt.Println("AFTER")
    }
    
    func main() {
        var ch chan string
    
        go service1(nil)
        fmt.Printf("sleep at :%d\n",time.Now().Unix())
        time.Sleep(time.Second * 2)
        fmt.Printf("weak at :%d\n",time.Now().Unix())
        for {
            select {
            case str := <-ch:
                fmt.Println(str)
            }
        }
    }
    

    执行结果如下:

    ➜  Q22 go run .
    sleep at :1562689190
    BEEFORE
    weak at :1562689192
    fatal error: all goroutines are asleep - deadlock!
    
    goroutine 1 [select (no cases)]:
    main.main()
            /Users/gaoke/work/go/mine/Q22/main.go:23 +0x19a
    
    goroutine 5 [chan send (nil chan)]:
    main.service1(0x0)
            /Users/gaoke/work/go/mine/Q22/main.go:10 +0x7b
    created by main.main
            /Users/gaoke/work/go/mine/Q22/main.go:17 +0x42
    exit status 2
    

    出现了我们期待的 all goroutines are asleep。可见所有线程都阻塞了,但是我们这个代码是想结果协程传来的字符串啊,为什么会阻塞呢。
    这里就涉及了 协程的知识了,因为我们只是简单声明了下chanch 还是nil.

    channelnil的时候,无论是传入数据还是取出数据,都会永久的block。

    回到我们代码,因为chnil,所以在service1中这个协程被永久的阻塞了,当我们在select的时候又被阻塞了。这也就造成了所有协程阻塞,出现死锁,代码panic。

    相关文章

      网友评论

          本文标题:干货 all goroutines are asleep - d

          本文链接:https://www.haomeiwen.com/subject/oocnfctx.html