码迷,mamicode.com
首页 > 其他好文 > 详细

golang fatal error: all goroutines are asleep - deadlock!

时间:2018-03-16 17:18:57      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:错误   ack   erro   关闭   自己   .net   管道   case   efault   

转自: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!

标签:错误   ack   erro   关闭   自己   .net   管道   case   efault   

原文地址:https://www.cnblogs.com/yorkyang/p/8582800.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!