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)    
}

执行效果:

参考:

http://stackoverflow.com/questions/26927479/go-language-fatal-error-all-goroutines-are-asleep-deadlock

 

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秒内执行效果截图:

 

如果避免上面异常抛出呢?这时候我们可以用 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)
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: go