Go 异常处理流程

在 Go 语言中,panicrecover 和 defer 是用于处理异常情况的关键字。它们通常一起使用来实现对程序错误的处理和恢复。

1. defer 语句

defer 用于在函数返回之前执行一段代码。被 defer 修饰的语句或函数会在包含 defer 的函数执行完毕后执行。defer 常用于资源清理、释放锁、关闭文件等操作。

func example() {
    defer fmt.Println("This will be executed last")
    fmt.Println("This will be executed first")
}

2. panic 和 recover

  • panic 用于引发运行时错误,导致程序崩溃。
  • recover 用于捕获 panic 引发的错误,并进行处理。
func example() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("Recovered from panic:", err)
        }
    }()
 
    panic("This will cause a panic")
}

3. 示例

  1. 当程序执行到 panic 语句时,它会立即停止当前函数的执行,并开始沿调用堆栈向上执行所有的 defer 语句。
  2. 执行 defer 语句时,将其推迟的函数或语句加入到一个栈中,但并不立即执行。
  3. 当所有的 defer 语句都被执行完毕后,程序会终止当前的函数执行,然后开始执行上一层函数的 defer 语句,以此类推。
  4. 如果在 defer 语句执行的过程中发生了 panic,则 panic 会被引发,但是在引发 panic 之前,会先执行该层级的 defer 语句。
  5. 如果有 recover 函数被调用,它会停止 panic 的传播,并返回传递给 panic 的值。

在 Go 中,一个协程(goroutine)出现 panic 不会直接影响其他协程的正常执行。Go 语言的设计目标之一是实现轻量级的并发,保持协程的独立性。因此,一个协程的 panic 不会波及到其他协程。

当一个协程发生 panic 时,通常会触发一系列的 defer 函数的执行,这提供了一种清理资源或记录日志等操作的机制。然后,Go 运行时系统会停止当前协程的执行,但不会影响其他正在运行的协程。

其他协程会继续执行,而不受 panic 影响。这是由于 Go 使用了处理异常的机制,而不是像传统的错误处理机制那样需要在每个函数中检查错误。在 Go 中,panic 主要用于表示程序遇到无法继续执行的错误情况。

下面是一个简单的例子,演示了一个协程的 panic 不会影响其他协程:

package main
 
import (
	"fmt"
	"sync"
	"time"
)
 
func main() {
	var wg sync.WaitGroup
 
	wg.Add(1)
	go func() {
		defer wg.Done()
		panicExample()
	}()
 
	// 启动另一个协程
	wg.Add(1)
	go func() {
		defer wg.Done()
		fmt.Println("Another goroutine is running.")
	}()
 
	// 等待所有协程结束
	wg.Wait()
}
 
func panicExample() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:", r)
		}
	}()
 
	fmt.Println("Start of panicExample")
	time.Sleep(1 * time.Second)
	panic("Something went wrong!")
	fmt.Println("End of panicExample") // 不会执行到这里
}

在这个例子中,panicExample 函数中的 panic 不会影响另一个协程的正常执行。虽然一个协程中发生了 panic,但其他协程仍然可以继续执行。

4. 总结

在Go中,runtime包是负责处理Go运行时(runtime)的细节,包括垃圾回收、协程调度等。当出现panic时,runtime包会负责处理这些异常情况。

当程序中出现panic时,Go运行时会按照以下步骤进行处理:

  1. 异常的传播:当一个函数发生panic时,该函数会立即停止执行,并将panic传播到调用它的函数。这个过程会一直向上传播,直到被捕获或程序终止。
  2. 栈的展开(Unwinding):在panic发生时,Go运行时会开始展开调用栈(stack unwinding)。这意味着它会逆序执行当前调用栈中的函数,直到找到一个能够处理panic的函数。
  3. 恢复(Recovery):在展开调用栈的过程中,Go运行时会寻找一个适当的recover函数来捕获并处理panicrecover函数是在当前协程的上下文中执行的,用于捕获并处理当前协程中的panic。如果找到了一个recover函数,并且它成功处理了panic(即没有再次触发panic),则程序会从发生panic的位置开始继续执行。
  4. 如果没有找到适当的recover函数来处理panic,程序将终止执行,并打印出相应的错误信息。

在处理panic时,需要注意以下几点:

  • panic通常表示程序中存在无法恢复的错误,因此应该尽量避免在正常的程序逻辑中使用panic
  • panicrecover是用于处理程序中的异常情况,而不是用于控制程序的正常流程。
  • recover函数只能在协程(goroutine)的执行过程中使用,并且只能捕获当前协程中的panic
  • 当一个协程出现panic时,其它协程不会受到影响,会继续独立执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/175272.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服务器 jupyter 文件名乱码问题

对于本台电脑,autodl服务器,上传中文文件时,从压缩包名到压缩包里的文件名先后会出现中文乱码的问题。 Xftp 首先是通过Xftp传输压缩包到Autodl服务器: 1、打开Xftp,进入软件主界面,点击右上角【文件】菜…

Nacos升级2.2.2 相关版本升级及升级中问题【下篇】

上篇对nacos进行了升级,如果有不清楚的小伙伴可以参考文章:https://blog.csdn.net/weixin_38801572/article/details/130237813 本篇主要是对升级后的鉴权问题进行处理,找了好多的文章都是添加username、password操作,但是实际操作…

8.3 Windows驱动开发:内核遍历文件或目录

在笔者前一篇文章《内核文件读写系列函数》简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于ZwQueryDirectoryFile这个内核API函数来实现,该函数可返回给定文件句柄指定的…

足底筋膜炎症状及治疗方法

足底筋膜炎是一种常见的足部疾病,通常会引起足跟疼痛和不适。这种疼痛通常在早晨起床后或者长时间休息后更为明显,行走一段时间后可能会减轻。下面我们将详细介绍足底筋膜炎的症状及治疗方法。 一、足底筋膜炎的症状 足跟疼痛:这是足底筋膜…

Avalonia 实现简单的IM即时通讯、视频通话(源码,支持国产系统,统信、银河麒麟)

Avalonia 在跨平台上的表现非常出色,对信创国产操作系统(像银河麒麟、统信UOS、Deepin等)也很不错。现在,我们就来使用 Avalonia 实现一个跨平台的简单IM,除了文字聊天外,还可以语音视频通话。废话不多说&a…

B032-服务器 Tomcat JavaWeb项目 Servlet

目录 服务器服务器的认识 Tomcat服务器Tomcat服务器的介绍Tomcat的安装Tomcat报错的情况Tomcat要启动成功的条件 JavaWeb项目Web的项目结构发布项目的第一种方式发布项目的第二种方式 Eclipse中搭建动态Web项目eclipse安装Tomcat插件servletservlet示例servlet的执行流程servle…

MySql 计算同比、环比

一、理论 国家统计局同比、环比计算公式 增长速度是反映经济社会某一领域发展变化情况的重要数据,而同比和环比是反映增长速度最基础、最核心的数据指标,也是国际上通用的指标。在统计中, 同比和环比通常是同比变化率和环比变化率的简称&…

【bug 回顾】上传图片超时

测试 bug 问题分析 - 上传图片超时 最近在测试上遇到一个莫名奇妙的问题,最后也没有得到具体是哪块的原因,看各位大佬有没有思路?? 一 、背景 现在我们有三台服务器,用来布两套环境。其中另外一台服务器3配置的 tom…

打包项目报错:程序包javax.servlet不存在

背景: WebService项目在没有配置Tomcat的情况下重新打包,由于是直接导入别人写好的项目,没有配置其他环境,所以报错程序包javax.servlet不存在 解决方法: 找到servlet-api.jar包,导入到现有项目的SDK 重…

深圳锐科达SV-X7 sip话机与海康威视摄像头联动设置方法

深圳锐科达SV-X7 sip话机与海康威视摄像头联动设置方法 SIP对讲终端获取设备IP地址方式 通过长按速拨键3秒(上电30秒后,即听到提示音后),待喇叭发出急促嘟嘟声,再快速按一下速拨键,设备自动语音播报本机的…

【开源】基于Vue.js的婚恋交友网站

项目编号: S 057 ,文末获取源码。 \color{red}{项目编号:S057,文末获取源码。} 项目编号:S057,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新…

CentOS7 FTP服务创建

一、安装FTP sudo dnf install vsftpd 二、设置防火墙,允许访问FTP //给防火墙增加一个允许的ftp服务(--permanent永久生效,重启后依然生效) sudo firewall-cmd --permanent --zonepublic --add-serviceftp//修改完后需要重启防火墙 sudo firewall-cmd --reload …

CSS特效014: hover后左右开门的效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧,主要包含CSS布局,CSS特效,CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点,CSS特效主要是一些动画示例,CSS花边是描述了一些CSS…

应对数据爆炸时代,揭秘向量数据库如何成为AI开发者的新宠,各数据库差异对比

项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实…

【OpenCV实现图像:OpenCV利用Python创作热力图】

文章目录 概要读取图像图像灰度化**像素化效果**小结 概要 热力图是一种强大的统计图表,通过对数据进行色彩映射,直观展示了数据分布的热度和密度。在绘制热力图时,关键在于指定颜色映射的规则,这决定了图中不同数值的呈现方式。…

vue中为什么data属性是一个函数而不是一个对象

面试官:为什么data属性是一个函数而不是一个对象? 一、实例和组件定义data的区别 vue实例的时候定义data属性既可以是一个对象,也可以是一个函数 const app new Vue({el:"#app",// 对象格式data:{foo:"foo"},// 函数格…

NX二次开发UF_CAM_opt_ask_subtypes 函数介绍

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_opt_ask_subtypes Defined in: uf_cam.h int UF_CAM_opt_ask_subtypes(const char * opt_type_name, UF_CAM_opt_stype_cls_t subtype_class, int * count, const char * * *…

CBC算法实践Demo

效果图 全部代码 package encryption001;import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64;public class EncryptionDemo {// 加密算法private static final String ALGORITHM "AES";// 加密模式和填充方式private s…

软件工程--软件建模--结构化方法通俗语言总结(暴肝超详解)(包含数据流图、数据字典、ER图、结构化设计和优化......)

目录 结构化分析 数据流图DFD 定义数据字典 实体关系图(E-R图) 结构化设计 变换映射 事务映射 优化结构设计 实例分析 详细设计(过程设计) 结构化方法是一种系统化开发软件的方法,该方法基于模块化的思想&am…

使用vue-cli搭建vue项目

1:安装vue-cli 命令:npm install -g vue/cli 2:查看安装的版本 vue --version 或者 vue -V 3:创建项目 vue create 项目名称 名称小写 4:vue2框架中根据自己的需求选择(我选择…