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!
评论





