美文网首页
关于 all goroutines are asleep 的问题

关于 all goroutines are asleep 的问题

作者: 上海大坤哥 | 来源:发表于2017-02-26 16:18 被阅读0次

    第一次见到这个错误,也是比较懵逼,如果自己搞不清这个问题为什么出现其实就是基本概念没理解清楚。下面我就说说这个问题。

    其实这个问题很简单,就是根据字面就可以解释,所有的 groutine 睡着了。说白了就是产生了死锁,而且是所有的goruntine(用户级别的)都发生了死锁。如下代码会报此错误

    
    package main
    
    import (
    
    "fmt"
    
    "sync"
    
    "time"
    
    )
    
    var a = sync.Mutex{}
    
    var b = sync.Mutex{}
    
    func main() {
    
    a.Lock()
    
    go block()
    
    time.Sleep(time.Second)
    
    b.Lock()
    
    fmt.Println("main")
    
    }
    
    func block() {
    
    b.Lock()
    
    a.Lock()
    
    fmt.Println("block")
    
    }
    
    

    以上代码,是两个goruntine 死锁,相当于两个goruntine都在等待对方,因此就出错了。但是如果单纯的理解为死锁也是不对的,因为在golang中不只死锁会引起此问题,看如下例子

    package main
    
    import "fmt"
    
    func main() {
        package main
    
    func main() {
        var a = make(chan int)
        a <- 1
        _ = <-a
    }
    
    

    这个例子是不是很神奇,先给 a 发送一个1,然后在接收就出问题了,这是为什么呢?我想应该很多没遇到这个问题的时候是想不明白的,这是因为 a <- 1 这个操作,是阻塞操作,就是说 遇到了 a<-1 代码就不走了,什么时候代码往下走?必须等到a里面的消息被读出去才会继续走,这个就不是锁引起的,所以单纯的理解为锁也是不对的。其实 alseep 才是最准确的描述方法,泛指引起goroutine挂起而且永远不会被唤醒的情况。

    知道了产生错误的原因其实就很容易避免了,做法无非就是想清楚逻辑,因为正确的逻辑是不会出现这种情况的,出现了问题就根据报错的地方,看一下就知道怎么回事了,前提是你理解了产生问题的原因

    相关文章

      网友评论

          本文标题:关于 all goroutines are asleep 的问题

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