当我们书写goroutines协程时,大家或许遇到下面的报错
fatal error: all goroutines are asleep - deadlock!
出现这个问题,就说明你的代码中管道是阻塞的
为了方便下次快速识别阻塞,遂进行如下总结
我们把channel看做成现实中的水管,水管的两端分别代表代表着channel的接受端和发送端。所以通道的阻塞自然有下面2种情况:
- 有接受端没有发送端或有发送端没有接受端(水管压根就不通,这是致命的)
- 接受端和输出端的速率不统一,造成的阻塞(接受端只接受一次,然后就关闭。所以接受端是阻塞的,因为channel是同步的,所以发送端也停止的了工作)
上述两种情况,就是我理解的阻塞,针对(1),这种情况是致命的,会出现文章开头的错误。可以参考如下代码:
package main
func main() {
out := make(chan int)
out <- 2
}
针对(2)现象,这种情况系统不会爆出致命错误,但其本质也是阻塞的。可以参考如下代码:
package main
import "fmt"
func main() {
ch1 := make(chan int)go pump(ch1) // pump hangs
fmt.Println(<-ch1) // prints only 0
}
func pump(ch chan int) {for i := 0; ; i++ {
ch <- i
}
}