子协程panic,主协程是否可以Recover?

1
小熊
小熊
管理员提问于4月前

无法在父协程中捕获子协程的panic

func main() {
    // 希望捕获所有所有 panic
    defer func () {
    r := recover()
        fmt.Println("捕获到子协程panic:",r)
    }()

    // 启动新协程
    go func () {
        panic(123)
    }()
    // 等待一下,不然协程可能来不及执行
    time.Sleep(1 * time.Second)
    fmt.Println("这条消息打印不出来")
}

输出

panic: 123

goroutine 6 [running]:
main.main.func2()
...
Process finished with exit code 2
  • 可以看到recover没有成功执行,整个进程都退出了
  • 所以开了新协程而且忘记了在协程中捕获panic的话,服务的进程就会因为某个未捕获的panic而退出。
  • 解决方法,使用结构体维护两个通道来处理donepanic事件,外部使用select来维护处理抛出panic,这样外部就可以recover