golang fatal error: all goroutines are asleep - deadlock!

来源:互联网 发布:免费淘宝网店模板 编辑:程序博客网 时间:2024/06/04 19:46

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

证明如下:

package mainimport (    "fmt"    "time")func main() {    c := make(chan int)    go func() {        for i := 0; i < 10; i++ {            c <- i        }    }()    hold(c)}func hold(c <-chan int) {    for {        time.Sleep(1 * time.Second)        fmt.Println(<-c)    }    fmt.Println("hold on ...")}

hold方法中无线循环获取数据,显然循环10次,就没有数据可以取了,于是抛出fatal error
再看一段测试代码

package mainimport (    "fmt")func afuntion(ch chan int) {    fmt.Println("finish")    <-ch}func main() {    ch := make(chan int)    ch <- 1    go afuntion(ch)}

这段代码同样会造成死锁,原因是 channel没有缓冲,相当于channel一直都是满的,所以这里会发生阻塞。下面的goroutine还为创建,所以程序会在此一直阻塞,然后。。。就挂掉了。。。
上面代码稍微修改下,就可以正常运行,如下

package mainimport (    "fmt")func afuntion(ch chan int) {    fmt.Println("finish")    <-ch}func main() {    ch := make(chan int)    go afuntion(ch)    ch <- 1}

解释:
1. 创建了一个无缓冲channel
2. 启动了一个goroutine,这个routine中对channel执行取出操作,但是因为这时候channel为空,所以这个取出操作发生阻塞,但是主routine可没有发生阻塞,程序继续运行
3. 往channel中放入了一个数据
4. 这时阻塞的那个routine检测到了channel中存在数据了,所以接触阻塞,从channel中取出数据,程序就此完毕

0 0