因為 fatal error: all goroutines are asleep - deadlock!
這種程序的異常退出,其實不是 "異常" 引起的,
例如 主協(xié)程因為 讀取管道發(fā)生阻塞 , 而且該阻塞沒有可能解除, 此時就會產(chǎn)生 deadlock
致命錯誤,從而導(dǎo)致程序異常退出, 但這不屬于異常的范疇,所以自然也就不能被 recover
捕獲
recover()
函數(shù)不能捕獲如下情況的異常:
(1) 如果在程序中直接os.Exit(0)
會導(dǎo)致程序直接退出,不會執(zhí)行defer
(2) 如果程序發(fā)生致命錯誤(fatal error
) 會導(dǎo)致程序直接退出,不會執(zhí)行defer
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println("在for循環(huán)中多次調(diào)用調(diào)用 t1 := <-timer1.C 引發(fā)異常:", err)
}
}()
timer1 := time.NewTimer(time.Millisecond)
for i := 0; i < 2; i++ {
t1 := <-timer1.C // 第二次執(zhí)行到這里程序會異常中斷,不會被defer捕捉,
// 因為嚴(yán)格來說這不是異常,而是 fatal error: all goroutines are asleep - deadlock!
// 因為 timer1.C 是一個 <-chan Time 類型的管道,該管道在觸發(fā)一次后會被置為nil,此時讀取它的值會發(fā)生阻塞
// 所以會發(fā)生deadlock
// 如果是多協(xié)程的話, 如果主協(xié)程要等待該協(xié)程的話,也會發(fā)生deadlock,否則只是該協(xié)程不會執(zhí)行完成,不會引發(fā)異常
// 綜上, defer不能捕捉該 "異常" , 因為這不是異常,而是程序邏輯錯誤
fmt.Printf("t1:%v\n", t1)
}
}