Go 的panic与recover
Go 的panic与recover
panic和recover调用时机
panic
能够改变程序的控制流,函数调用panic
时会立刻停止执行函数的其他代码,并在执行结束后在当前 Goroutine 中递归执行调用方的延迟函数调用defer
;recover
可以中止panic
造成的程序崩溃。它是一个只能在defer
中发挥作用的函数,在其他作用域中调用不会发挥任何作用;panic
只会触发当前 Goroutine 的延迟函数调用;recover
只有在defer
函数中调用才会生效;panic
允许在defer
中嵌套多次调用;
panic
- panic不允许跨协程
panic真正的程序崩溃的过程:
编译器会将关键字 panic
转换成 runtime.gopanic
,该函数的执行过程包含以下几个步骤:
- 创建新的
runtime._panic
结构并添加到所在 Goroutine_panic
链表的最前面; - 在循环中不断从当前 Goroutine 的
_defer
中链表获取runtime._defer
并调用runtime.reflectcall
运行延迟调用函数; - 调用
runtime.fatalpanic
中止整个程序
崩溃恢复:
编译器会将关键字 recover
转换成 runtime.gorecover
这个函数的实现非常简单,如果当前 Goroutine 没有调用 panic
,那么该函数会直接返回 nil
,这也是崩溃恢复在非 defer
中调用会失效的原因。
在正常情况下,它会修改 runtime._panic
结构体的 recovered
字段,runtime.gorecover
函数本身不包含恢复程序的逻辑,程序的恢复也是由 runtime.gopanic
函数负责的:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Joohwan!
评论