GoLong的学习之路,进阶,语法之并发(并发错误处理)补充并发三部曲

news2024/12/26 22:55:01

这篇文章主要讲的是如何去处理并发的错误。

在Go语言中十分便捷地开启goroutine去并发地执行任务,但是如何有效的处理并发过程中的错误则是一个很棘手的问题。

文章目录

  • recover
  • errgroup

recover

哦对,似乎没写错误处理的文章。后面补上。

首先,这里的recover通常用来错误处理。

我们可以在代码中使用 recover 来会恢复程序中弹出的 panic,而 panic 只会触发当前 goroutine 中的 defer 操作。

func f1() {
	defer func() {
		if e := recover(); e != nil {
			fmt.Printf("recover panic:%v\n", e)
		}
	}()
	// 开启一个goroutine执行任务
	go func() {
		fmt.Println("in goroutine....")
		// 只能触发当前goroutine中的defer
		panic("panic in goroutine")
	}()

	time.Sleep(time.Second)
	fmt.Println("exit")
}
func main() {
	f1()
}

在这里插入图片描述
从输出结果可以看到程序并没有正常退出,而是由于 panic 异常退出了(exit code 2)。

正如上面示例演示的那样,在启用 goroutine 去执行任务的场景下,如果想要 recover goroutine中可能出现的 panic 就需要在 goroutine 中使用 recover

在这里插入图片描述
程序中的 panic 被 recover 成功捕获,程序最终正常退出。

errgroup

我们通常在使用goroutine是 调用一个函数或匿名函数

go func(){
  // ...
}

go foo()

并发的那些函数,其实很难拿的准。错误信息只多不少。

当我们想要将一个任务拆分成多个子任务交给多个 goroutine 去运行,这时我们该如何获取到子任务可能返回的错误呢?

// fetchUrlDemo 并发获取url内容
func FetchUrlDemo() {
	wg := sync.WaitGroup{}
	var urls = []string{
		"http://www.baidu.com",
		"http://www.qq.com",
		"http://www.nihaosfasdfasdf.com",
	}

	for _, url := range urls {
		wg.Add(1)
		go func(url string) {
			defer wg.Done()
			resp, err := http.Get(url)
			if err == nil {
				fmt.Printf("获取%s成功\n", url)

				resp.Body.Close()
			}
			return // 如何将错误返回呢?
		}(url)
	}
	wg.Wait()
	// 如何获取goroutine中可能出现的错误呢?
}

上面的示例代码中,我们开启了 3 个 goroutine 分别去获取3个 url 的内容。

类似这种将任务分为若干个子任务的场景会有很多,那么我们如何获取子任务中可能出现的错误呢?

errgroup 包就是为了解决这类问题而开发的.

它能为处理公共任务的子任务而开启的一组 goroutine 提供同步error 传播和基于context 的取消功能。

errgroup 包中定义了一个 Group 类型,它包含了若干个不可导出的字段。

type Group struct {
	cancel func()

	wg sync.WaitGroup

	errOnce sync.Once
	err     error
}

errgroup.Group 提供了GoWait两个方法。

Go : func (g *Group) Go(f func() error)

  • Go 函数会在新的 goroutine 中调用传入的函数f。

  • 第一个返回非零错误的调用将取消该Group;下面的Wait方法会返回该错误

Wait:func (g *Group) Wait() error

  • Wait 会阻塞直至由上述 Go 方法调用的所有函数都返回,然后从它们返回第一个非nil的错误(如果有)
// fetchUrlDemo2 使用errgroup并发获取url内容
func fetchUrlDemo2() error {

	g := new(errgroup.Group) // 创建等待组(类似sync.WaitGroup)
	var urls = []string{
		"http://www.4399.com",
		"http://www.baidu.com",
		"http://www.sdhfjoahoesrh.com",
	}
	for _, url := range urls {
		url := url // 注意此处声明新的变量
		// 启动一个goroutine去获取url内容
		g.Go(func() error {
			resp, err := http.Get(url)
			if err == nil {
				fmt.Printf("获取%s成功\n", url)
				resp.Body.Close()
			}
			return err // 返回错误
		})
	}
	if err := g.Wait(); err != nil {
		// 处理可能出现的错误
		fmt.Println(err)
		return err
	}
	fmt.Println("所有goroutine均成功")
	return nil
}

func main() {
	fetchUrlDemo2()

}

在这里插入图片描述

当子任务的 goroutine 中对,http://www.sdhfjoahoesrh.com,发起 HTTP 请求时会返回一个错误,这个错误会由 errgroup.GroupWait 方法返回。

在这里插入图片描述

通过阅读 errgroup.Group 的 Go 方法源码,我们可以看到当任意一个函数 f 返回错误时,会通过g.errOnce.Do只将第一个返回的错误记录,并且如果存在 cancel 方法则会调用cancel

那么如何创建带有 cancel 方法的 errgroup.Group ?
func WithContext(ctx context.Context) (*Group, context.Context)

WithContext 函数接收一个父 context,返回一个新的 Group 对象一个关联的子 context 对象

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac 本地部署thinkphp8【配置环境】

PHP开发工具 我这里选择的是VSCode,里面安装PHP插件 把thinkphp的项目放到 切换到phpenv ![在这里插入图片描述](https://img-blog.csdnimg.cn/a15cc442fab74754ad86d74f6d9942e5.png URL重写如果不改,在请求的时候地址是这样的‘http://tp.com/index.php…

数据可视化模板案例:制造业提高生产力的关键

一、模板背景 在这个信息爆炸的时代,数据对于企业的成功至关重要。制造业作为全球经济的重要组成部分,如何有效利用数据提高生产效率、降低成本、优化决策,已成为行业关注的焦点。 二、方案思路 配⾊ - 科技蓝,贴合⼯业主题。 …

【算法与数据结构】78、90、LeetCode子集I, II

文章目录 一、题目二、78.子集三、90.子集II三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、78.子集 思路分析:【算法与数据结构】77、LeetCode组合。本题可以参考77题的组合问题代码&#xff0…

/etc/init.d/functions: Syntax error: “(“ unexpected (expecting “done“)

一.问题描述: ubuntu系统安装服务时报错: 二.问题解析: Ubuntu安装时默认使用dash,shell脚本命令失败,需要安装bash来运行,长期解决该问题就是重新配置dash 三:问题解决: sudo dpkg-reconfi…

迅为龙芯2K1000开发板虚拟机ubuntu启动root用户

作为嵌入式开发人员,系统的所有权限都要为我们打开,所以我们不必像运维那样,对 root 用户非常敏感,所以安装完 ubuntu 系统以后,我们要启用 root 用户。 首先我们打开 ubuntu 控制终端,然后在终端里面输入…

wireshark抓包并进行Eigrp网络协议分析

路由协议 Eigrp ​ EIGRP:Enhanced Interior Gateway Routing Protocol 即 增强内部网关路由协议。也翻译为 加强型内部网关路由协议。 EIGRP是Cisco公司的私有协议(2013年已经公有化)。 EIGRP结合了链路状态和距离矢量型路由选择协议的Cisco专用协议&a…

银行数据中心机房动力环境监控系统设计与优化

安科瑞电气股份有限公司 上海嘉定201801 摘要:结合银行数据中心建设项目,设计银行数据中心机房动力环境监控系统,分析银行数据中心机房监控对象、搭建系统监控架构,给出监控实现方法,*后针对运行一段时间出现的问题&a…

关于淘宝API接口你必须了解的API2.0

据说API从1.0升级到2.0啦?今天我们来聊一聊关于淘宝API接口你必须了解的API2.0 然而 作为新手小白 …… 并不懂API是毛线 好吧 …… 今天 我们就来上一堂小白入门课 几句话聊聊API 高级淘客 请忽略 请批评 请交流 还有请看到最底下 有重磅消息&#xf…

人大女王金融硕士毕业生:追风而遇、沐光同行;心羽为翼,不负韶华!

中国人民大学-加拿大女王大学金融硕士2022-2023级行业高管班 新加坡大东方人寿北京代表处首席代表 01、社会发展推动金融业持续迭代,为更好应对未来挑战,持续学习和自我升级非常重要! 2015年以来,新一代数字化和智能化信息技术…

halcon获取轮廓属性的时候报错:Contour attribute not defined(HALCON错误代码:3261)

报错截图: 在使用以下算子,获取xld的distance属性时,或者其他属性时报错。 get_contour_attrib_xld (ObjectSelected, distance, Attrib) 如果是属性报错。这里需要在调用获取轮廓属性之前先获得轮廓之间的距离。 使用以下算子:…

如何构建可视化设计中的视觉层次?

【什么是视觉层次感】 第一层级:主导元素,即最重要的视觉信息。能够很清晰的传达最重要的信息,你的主导层级通常由图形或者重要的视觉原色组成; 第二层级:应该是数据焦点,引导用户查看重要的数据指标&…

解决@Autowired警告

一.前言 再使用springboot自动注入Autowired注解时,下方会出现波浪线警告,这是什么原因呢?我们细看提示说明已经说的很清楚了,Field injection is not recommended “不建议使用字段注入”,字段注入是指通过直接将依赖项注入到类的字段中来实现依赖注入。这种方式存在一些问题…

网易数帆:云原生向左,低代码向右

网易数帆,前身是网易杭州研究院于2016年孵化的网易云,历经7载探索与沉淀,如今已进化成为覆盖云原生、低代码、大数据和人工智能四大技术赛道的数智化服务提供商,服务于金融、央国企、能源、制造等领域300余家头部企业。 近日&…

『亚马逊云科技产品测评』活动征文|Amazon EC2 的讲解及相关服务

授权声明:本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 Developer Centre, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 Amazon EC2 的讲解及相关服务 一、什么是 Amazon EC2?二、何为…

centos7 安装网络文件共享NFS详细过程

网络文件系统,英文Network File System(NFS),是由SUN公司研制的UNIX表示层协议(presentation layer protocol),能使使用者访问网络上别处的文件就像在使用自己的计算机一样。 多个服务器之间需要共享文件,通过NFS服务共享是一个简…

“咸阳杯·美洲队中国行”国际足球邀请赛圆满举办

巴拿马1:0乌拉圭 “咸阳杯美洲队中国行”国际足球邀请赛圆满举办 11月12日下午3:00,由陕旅集团联合承办、陕体集团协办的“咸阳杯美洲队中国行”国际足球邀请赛在咸阳奥体中心开赛。两支美洲劲旅:巴拿马国家队与乌拉圭国青队龙争虎斗&#…

基于springboot实现生鲜超市管理的设计与实现系统【项目源码】计算机毕业设计

基于springboot实现生鲜超市管理的设计与实现系统演示 Java技术 Java是由Sun公司推出的一门跨平台的面向对象的程序设计语言。因为Java 技术具有卓越的通用性、高效性、健壮的安全性和平台移植性的特点,而且Java是开源的,拥有全世界最大的开发者专业社群…

AlNiCo铝镍钴永磁材料

1970年代稀土永磁材料发明之前,AlNiCo铝镍钴合金一直是磁性能最强的永磁材料,不过由于成分中包含战略性金属钴和镍,导致成本较高,随着铁氧体永磁和稀土永磁的相继问世,铝镍钴材料在众多应用中逐步被取代。但在一些高温…

屏幕截图软件 Snagit mac中文版软件特点

Snagit mac是一款屏幕截图和视频录制软件,它可以帮助用户快速捕捉屏幕上的任何内容,并将其编辑、标注和共享。 Snagit mac软件特点 多种截图模式:支持全屏截图、窗口截图、区域截图、延时截图等多种截图模式,满足不同用户的需求。…

求求了 谁好人家还搞托运!!

求求了 谁好人家还搞托运!! 真相了 是我这个好人 转眼又是一年之冬 北方的朋友已经开始“南迁”了 或者在北方生长的宝子也会不习惯冬天吗? 你又是来自哪个城市呢? 所以过冬这件事情不容小觑 而中国唯一的热带气候省份-海南 就成了香饽饽 但有个问题令人犯愁 北方来到中国最南…