脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - Golang中panic与recover的区别

Golang中panic与recover的区别

2022-10-14 11:43谈笑风生间 Golang

这篇文章主要介绍了Golang中panic与recover的区别,文章基于Golang的基础内容展开panic与recover的区别介绍,需要的小伙伴可以参考一下

前言

与defer类似的是,goroutine 中也有一个_panic链表头指针指向一个_panic链,发生panic的时候也是在链表头插入_panic结构体(执行gopanic)

在执行过程中发生了panic。那么panic以后的代码不会执行,转而执行panic的逻辑,再执行defer,执行到的defer要将started标记为true,同时将其defer结构体中的_panic指针指向当前的_panic,表示这个defer是由该panic触发的。再去执行defer链表,如果defer执行中还触发了panic,panic后的代码不载执行,将这个panic插入panic链头,同时将其作为当前panic。当遇到了与当前panic不符的defer,就找到该defer上的panic,将其标记为已终止,从defer链表中移除当前执行的defer。打印panic移除信息,从链表尾开始逐步输出

流程

panic执行defer的流程:

  • 先标记started=true,_panic=&panic
  • 后释放
  • 目的是为了终止之前发生的panic

异常信息的输出方式:

  • 所有还在panic链表上的项会被输出
  • 顺序与发生panic的顺序一致

Golang中panic与recover的区别

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// A _panic holds information about an active panic.
//
// A _panic value must only ever live on the stack.
//
// The argp and link fields are stack pointers, but don't need special
// handling during stack growth: because they are pointer-typed and
// _panic values only live on the stack, regular stack pointer
// adjustment takes care of them.
type _panic struct {
    // argp 存储当前要执行的defer的函数参数地址
    argp      unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
    // arg panic函数自己的参数
    arg       interface{}    // argument to panic
    // link,链到之前发生的panic
    link      *_panic        // link to earlier panic
    pc        uintptr        // where to return to in runtime if this panic is bypassed
    sp        unsafe.Pointer // where to return to in runtime if this panic is bypassed
    // recovered 标识panic是否被恢复
    recovered bool           // whether this panic is over
    // aborted 标识panic是否被终止
    aborted   bool           // the panic was aborted
    goexit    bool
}

关于recover

recover只执行一件事

  • 将当前执行的panic的recovered字段置为true

在每个defer执行完以后panic处理流程都会检查当前panic是否被recover

  • 如果当前panic已经被恢复,就会将它从panic链中移除
  • 执行到的defer也会被移除,同时要保存_defer.sp和_defer.pc

利用_defer.sp和_defer.pc跳出当前panic的处理流程,通过栈指针判断,只执行当前函数中注册的defer函数

Golang中panic与recover的区别

在发生recover的函数正常结束后才会进入到检测panic是否被恢复的流程

当recover的函数又发生panic时,goroutine会将该panic加入到链头,设置为当前panic,再去执行defer链表,发现当前defer是当前panic执行的,移除当前defer,继续执行下一个,直到发现不是当前panic执行的,在panic链上找到那个panic,输出异常信息

对于已经recover标记的panic在输出异常信息时会加上recovered标记

Golang中panic与recover的区别

到此这篇关于Golang中panic与recover的区别的文章就介绍到这了,更多相关Go panic recover内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/7102402219504320543

延伸 · 阅读

精彩推荐
  • Golang详解Go语言的context包从放弃到入门

    详解Go语言的context包从放弃到入门

    这篇文章主要介绍了Go语言的context包从放弃到入门,本文通过实例演示给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可...

    雪山飞猪9562021-02-22
  • Golang一文读懂go中semaphore(信号量)源码

    一文读懂go中semaphore(信号量)源码

    这篇文章主要介绍了一文读懂go中semaphore(信号量)源码的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友...

    Rick.lz6772021-04-23
  • GolangGo语言简介和环境配置

    Go语言简介和环境配置

    Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发速度和易维护性,有人形容Go语言:Go= C + Python , 说明Go语言既有C静态语言程序的...

    吃个大份黄焖鸡9082022-07-13
  • GolangGolang原生rpc(rpc服务端源码解读)

    Golang原生rpc(rpc服务端源码解读)

    本文主要介绍了Golang原生rpc(rpc服务端源码解读),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    鹿灏楷silves7082022-09-13
  • Golanggoland设置颜色和字体的操作

    goland设置颜色和字体的操作

    这篇文章主要介绍了goland设置颜色和字体的操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    igoodful5392021-06-18
  • GolangGolang中channel的原理解读(推荐)

    Golang中channel的原理解读(推荐)

    channel主要是为了实现go的并发特性,用于并发通信的,也就是在不同的协程单元goroutine之间同步通信。接下来通过本文给大家介绍Golang中channel的原理解读,...

    可问春风丶5102021-11-22
  • GolangGolang中Interface接口的三个特性

    Golang中Interface接口的三个特性

    本文详细讲解了Golang中Interface接口的三个特性,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...

    WingPig8122022-07-19
  • Golanggolang实现简单工厂、方法工厂、抽象工厂三种设计模式

    golang实现简单工厂、方法工厂、抽象工厂三种设计模式

    这篇文章介绍了golang实现简单工厂、方法工厂、抽象工厂三种设计模式的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借...

    李慢慢2336932022-09-13