golang fatal error: all goroutines are asleep - deadlock!

Posted yorkyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang fatal error: all goroutines are asleep - deadlock!相关的知识,希望对你有一定的参考价值。

转自:https://www.cnblogs.com/ghj1976/p/4295013.html

http://blog.csdn.net/skh2015java/article/details/60330785

channel默认上是阻塞的,也就是说,如果Channel满了,就阻塞写,如果Channel空了,就阻塞读。阻塞的含义就是一直等到轮到它为止。单有时候我们会收到 fatal error: all goroutines are asleep - deadlock!  异常,这是如何呢?

代码例子:

package main

import "fmt"

func main() { 
    channel := make(chan string, 2)

    fmt.Println("1") 
    channel <- "h1" 
    fmt.Println("2") 
    channel <- "w2" 
    fmt.Println("3") 
    channel <- "c3"    // 执行到这一步,直接报 error 
    fmt.Println("...") 
    msg1 := <-channel 
    fmt.Println(msg1) 
}

执行效果:

技术分享图片

fatal error: all goroutines are asleep - deadlock!

出错信息的意思是: 
在main goroutine线,期望从管道中获得一个数据,而这个数据必须是其他goroutine线放入管道的 
但是其他goroutine线都已经执行完了(all goroutines are asleep),那么就永远不会有数据放入管道。 
所以,main goroutine线在等一个永远不会来的数据,那整个程序就永远等下去了。 
这显然是没有结果的,所以这个程序就说“算了吧,不坚持了,我自己自杀掉,报一个错给代码作者,我被deadlock了”

 

这里是系统自动在除了主协程之外的协程都关闭后,做的检查,继而报出的错误, 证明思路如下, 在100秒内, 我们看不到异常, 100秒后,系统报错。

package main

import ( 
    "fmt" 
    "time" 
)

func main() { 
    channel := make(chan string, 2)

    go func() { 
        fmt.Println("sleep 1") 
        time.Sleep(100 * time.Second) 
        fmt.Println("sleep 2") 
    }()

    fmt.Println("1") 
    channel <- "h1" 
    fmt.Println("2") 
    channel <- "w2"

    fmt.Println("3") 
    channel <- "c3"

    fmt.Println("...") 
    msg1 := <-channel 
    fmt.Println(msg1) 
}

100秒内执行效果截图:

技术分享图片

100秒后执行效果截图:

技术分享图片

如果避免上面异常抛出呢?这时候我们可以用 select来帮我们处理。

package main

import "fmt"

func main() { 
    channel := make(chan string, 2)

    fmt.Println("1") 
    channel <- "h1" 
    fmt.Println("2") 
    channel <- "w2"

    fmt.Println("3") 
    select {

    case channel <- "c3": 
        fmt.Println("ok") 
    default: 
        fmt.Println("channel is full !") 
    }

    fmt.Println("...") 
    msg1 := <-channel 
    fmt.Println(msg1) 
}

执行效果:

技术分享图片

这时候,我们把第三个要写入的 chan 抛弃了。

 

上面的例子中是写的例子, 读的例子也一样,下面的异常是  ws := <-channel 这一行抛出的。

channel := make(chan string, 2)

fmt.Println("begin") 
ws := <-channel 
fmt.Println(ws)

技术分享图片

 












































以上是关于golang fatal error: all goroutines are asleep - deadlock!的主要内容,如果未能解决你的问题,请参考以下文章

golang fatal error: concurrent map read and map write

PHP Fatal error: Uncaught ErrorException: preg_match_all (): JIT compilation failed: no more memory

[ERR] collect2: fatal error: cannot find 'ld'

php捕获Fatal error错误与异常处理

logback的简单分析

Golang错误处理