30

Go语言之panic和recover

 4 years ago
source link: https://studygolang.com/articles/25469
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

转自“灰子学技术”,原文链接: https://mp.weixin.qq.com/s/cfPY26_zOzFFSuPbElDU-Q

写在前面的话:

panic是Go语言中,用于终止程序的一种函数,往往用在下面两种情况:1)程序出现了很大的故障,例如不能在提供服务了。2)程序在运行阶段碰到了内存异常的操作,例如空指针的取值,改写只读内存等。

对于panic来说,1)场景往往是主动调用; 2)场景则是被动调用,panic一旦产生之后,会将堆栈里面的数据dump出来,这样就方便了开发人员来定位问题。

recover是用来截获panic异常信息的,截获了之后,可以控制程序跳过panic的地方继续执行。

本文笔者主要分享下,调用panic之后都做了哪些操作,以及recover使用之后的效果。

1. panic使用介绍

panic一旦触发之后,会按照下面的顺序来做处理:

1)panic开始的地方启动终止程序操作。

2)调用当前触发panic函数里面的defer函数。

3)返回该函数的调用方,当作异常返回来处理,所以这一步也会调用调用方函数的defer,一直到没有调用方为止。

4)打印panic的信息。

5)打印堆栈跟踪信息,也就是我们看到的函数调用关系。

6)终止程序。

例子:

eqeEvuN.png!web

结果分析:通过输出结果我们可以看出,1)2调用了panic开始了panic的操作, 3出不在执行,故没有打印。2)执行testPanic中的defer函数,输出了"testPanic exit!" 。3) 接着,返回到调用方main函数,当作异常终止,调用main中的defer函数,打印"main exit!",main中的6处代码也被跳过执行。 4) 打印panic触发时的错误信息"trigger panic!" 。5)打印panic的调用堆栈信息,这里是从触发panic的点开始的,一层层往上调用。6)退出程序。

2. recover使用介绍

recover是go提供的一个用来截获panic信息,重新获取协程控制的函数。它的使用,有两点需要注意,1)recover只能在defer函数中使用。2)recover的使用必须于触发panic的协程是同一个协程才行。

例子1,同一个协程中:

beeyqiU.png!web

结果分析:通过调用recover之后的结果来看,panic被1处的recover成功截获,只是3处到代码没有执行而已,对于调用testPanic的main函数后续代码都被执行了,"main end!"信息也被打印出来了。

例子2,panic和recover在不同协程中,不能恢复

MNbIVrI.png!web

结果分析:通过输出结果可以看出,就算我们在4处调用了rcover,但是panic也没有被截获,原因就是panic在子协程中,而recover在主协程中,recover不能跨协程截获panic信息。

3.补充知识:

对于panic显示的函数堆栈调用关系,debug.PrintStack()也可以做到,它就是用来打印函数的堆栈调用关系的, 例子如下所示:

YRfeYnM.png!web

下面是panic和recover两个函数的解释说明: https://golang.org/src/builtin/builtin.go?h=panic#L232

qeAzQrQ.png!web

灰子学技术:

ABBRFna.jpg!web


Recommend

  • 85

    Welcome to tutorial no. 33 in

  • 58
    • jiajunhuang.com 5 years ago
    • Cache

    Go语言的defer, panic和recover

    本文源自 https://blog.golang.org/defer-panic-and-recover defer defer语句在Go的函数中属于一个栈的形式,即在函数运行完成时,根据该语句...

  • 49
    • studygolang.com 5 years ago
    • Cache

    Defer, Panic, Recover

    1、简介 Go具有控制流程的常用机制:if,for,switch,goto。 它还有go语句在单独的goroutine中运行代码。 在这里,我想讨论一些不太常见的问题:Defer,Panic和Recover。 2、Defer Defer语句将函数调...

  • 61
    • studygolang.com 5 years ago
    • Cache

    Go的Defer、Panic和Recover (翻译)

    翻译自: https://blog.golang.org/defer-panic-and-recover Go有和语言一样常见的流程控制语句:if, for, switch, goto。同时也可以使用go语句实现在不...

  • 41
    • studygolang.com 5 years ago
    • Cache

    defer,panic 和 Recover

    翻译自: https://blog.golang.org/defer-panic-and-recover Golang的常用控制流程机制有:if,for,switch,goto,他还有go语句启动goroutine运行代码。...

  • 67
    • draveness.me 5 years ago
    • Cache

    谈谈 panic 和 recover 的原理

    这一节中我们将介绍 Go 语言中两个经常成对出现的关键字 panic 和 recover 的实现原理,我们在上一节关注的defer 与这里介绍的两个关键字其实也有着比较大的关系,我们会在剩下的部分展开介绍相关的内容,没有...

  • 42
    • studygolang.com 5 years ago
    • Cache

    Go的Defer、Panic和Recover

    作者:Andrew Gerrand 翻译: https://blog.golang.org/defer-panic-and-recover 知乎:

  • 40
    • www.tuicool.com 4 years ago
    • Cache

    【Go】了解Defer、Panic、Recover

    Go 有流程控制的机制: if 、 for 、 switch 、 goto 。这里我们讨论并不常见的: defer 、 panic 、 recover 。

  • 24
    • studygolang.com 4 years ago
    • Cache

    Go defer, panic&recover

    Go defer, panic&recover 定义与使用 defer A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns...

  • 39
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    Defer,Panic,and Recover

    不忘初心,砥砺前行   作者 | 陌无崖 转载请联系授权  Defer,Panic...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK