golang fatal error: all goroutines are asleep

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

证明如下:

package main

import (
    "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 main

import (
    "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 main

import (
    "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中取出数据,程序就此完毕

用放荡不羁的心态过随遇而安的生活
原文地址:https://www.cnblogs.com/re-myself/p/5532479.html