关于 all goroutines are asleep 的问题

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

其实这个问题很简单,就是根据字面就可以解释,所有的 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 的问题)