疑难杂症:recover不能捕获deadlock异常

因为 fatal error: all goroutines are asleep - deadlock! 这种程序的异常退出,其实不是 "异常" 引起的,
例如 主协程因为 读取管道发生阻塞 , 而且该阻塞没有可能解除, 此时就会产生 deadlock 致命错误,从而导致程序异常退出, 但这不属于异常的范畴,所以自然也就不能被 recover 捕获

recover() 函数不能捕获如下情况的异常:
(1) 如果在程序中直接 os.Exit(0) 会导致程序直接退出,不会执行 defer
(2) 如果程序发生致命错误(fatal error) 会导致程序直接退出,不会执行 defer

func main() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("在for循环中多次调用调用 t1 := <-timer1.C 引发异常:", err)
        }
    }()
    timer1 := time.NewTimer(time.Millisecond)
    for i := 0; i < 2; i++ {
        t1 := <-timer1.C  // 第二次执行到这里程序会异常中断,不会被defer捕捉,
        // 因为严格来说这不是异常,而是 fatal error: all goroutines are asleep - deadlock!
        // 因为 timer1.C 是一个 <-chan Time 类型的管道,该管道在触发一次后会被置为nil,此时读取它的值会发生阻塞
        // 所以会发生deadlock
        // 如果是多协程的话, 如果主协程要等待该协程的话,也会发生deadlock,否则只是该协程不会执行完成,不会引发异常
        // 综上, defer不能捕捉该 "异常" , 因为这不是异常,而是程序逻辑错误
        fmt.Printf("t1:%v\n", t1)
    }
}

你可能感兴趣的:(疑难杂症:recover不能捕获deadlock异常)