如何实现若干子任务一损俱损--浅谈errgroup
errgroup 是 Go 语言官方扩展库 x/sync 中的一个包,它提供了一种方式来并行运行多个 goroutine,并在所有 goroutine 都完成时返回第一个发生的错误(如果有的话)。这对于需要并行处理多个任务并等待它们全部完成,同时需要处理其中任何一个可能发生的错误的场景非常有用。
errgroup 是 Go 语言中用于管理多个 goroutine 的同步和错误处理的库。使用 errgroup 可以简化并发代码的编写,使得错误处理更加简洁和一致。
注意:goroutine任务需要有取消功能才能立即终止其它任务返回。
errgroup可以等待所有任务完成再返回,也可以等到第一个错误出现时终止其它任务,取决于业务逻辑。
它的主要作用包括:
- 同步: errgroup.Group 提供了一个 Wait 方法,这个方法会阻塞调用者,直到组内的所有goroutine都完成执行。
- 错误传播: errgroup 能确保第一个发生的错误会被立即传播给所有其他goroutine,这样可以避免在多个并发任务中检查每个任务的状态,简化错误处理逻辑。
- 取消上下文: errgroup 结合 context.Context 使用,可以在外部请求取消时,通知所有goroutine停止执行。返回第一个错误原因。
- 限制并发: 通过 SetLimit 方法,errgroup 可以限制同时运行的goroutine数量。配合done()方法。cancel()触发done()。
案例1
fetch其中一个报错了,其它的goroutine还在运行。errgroup返回的是最后一个错误。
package mainimport ("errors""fmt""golang.org/x/sync/errgroup""math/rand""time"
)func fetch(url string) (string, error) {randomNumber := rand.Intn(10) + 5fmt.Println(randomNumber)time.Sleep(time.Duration(randomNumber) * time.Second)fmt.Println("fetch")return url, errors.New("error happens")
}func main() {urls := []string{"http://example.com","http://example.org","http://example.net",}rand.Seed(time.Now().UnixNano())var eg errgroup.Groupfor _, url := range urls {eg.Go(func() error {body, err := fetch(url)if err != nil {return err}fmt.Printf("Fetched %s: %s\n", url, body)return nil})}if err := eg.Wait(); err != nil {fmt.Printf("Failed to fetch one or more URLs: %v\n", err)}
}
输出:
14
7
9
fetch
fetch
fetch
Failed to fetch one or more URLs: error happens
这个并不是我们想要的结果,我们期望其中一个goroutine报错后,其它的任务终止。
案例2
当碰到错误会立即停止所有goroutine。
package mainimport ("context""errors""fmt""golang.org/x/sync/errgroup""strings""time"
)func main() {queryUrls := map[string]string{"url1": "http://localhost/url1","url2": "http://localhost/url2","url3": "http://localhost/url3",}var results []stringctx, cancel := context.WithCancel(context.Background())eg, errCtx := errgroup.WithContext(ctx)for _, url := range queryUrls {url := urleg.Go(func() error {result, err := query(errCtx, url)if err != nil {//其实这里不用手动取消,看完源码就知道为啥了cancel()return err}results = append(results, fmt.Sprintf("url:%s -- ret: %v", url, result))return nil})}err := eg.Wait()if err != nil {fmt.Println("eg.Wait error:", err)return}for k, v := range results {fmt.Printf("%v ---> %v\n", k, v)}
}func query(errCtx context.Context, url string) (ret string, err error) {fmt.Printf("请求 %s 开始....\n", url)// 假设这里是发送请求,获取数据if strings.Contains(url, "url2") {// 假设请求 url2 时出现错误time.Sleep(time.Second * 2)return "", errors.New("请求出错")} else if strings.Contains(url, "url3") {// 假设 请求 url3 需要1秒select {case <-errCtx.Done():ret, err = "", errors.New("请求3被取消")fmt.Println("请求3被取消")returncase <-time.After(time.Second * 3):fmt.Printf("请求 %s 结束....\n", url)return "success3", nil}} else {select {case <-errCtx.Done():ret, err = "", errors.New("请求1被取消")fmt.Println("请求1被取消")returncase <-time.After(time.Second):fmt.Printf("请求 %s 结束....\n", url)return "success1", nil}}}
输出:
请求 http://localhost/url2 开始....
请求 http://localhost/url3 开始....
请求 http://localhost/url1 开始....
请求 http://localhost/url1 结束....
请求3被取消
eg.Wait error: 请求出错
eg.Wait() 会阻塞,直到所有的 goroutine 都完成执行或者其中一个 goroutine 返回了错误。如果有错误发生,eg.Wait() 会返回第一个遇到的错误。
通过使用 errgroup,我们可以更容易地管理多个 goroutine,并在其中一个 goroutine 发生错误时取消其他 goroutine。
相关文章:
如何实现若干子任务一损俱损--浅谈errgroup
errgroup 是 Go 语言官方扩展库 x/sync 中的一个包,它提供了一种方式来并行运行多个 goroutine,并在所有 goroutine 都完成时返回第一个发生的错误(如果有的话)。这对于需要并行处理多个任务并等待它们全部完成,同时需…...
并查集的基础题
## 洛谷p1196 绿 35m 点到祖先的距离 代码: #include<bits/stdc.h> using namespace std; const int N3e510; int f[N],dist[N],num[N];//num计算祖先有多少儿子 ,dist计算距离祖先有几个 int zx(int x){ if(f[x]x)return x;//x没爸爸 e…...
[论文翻译] LTAChecker:利用注意力时态网络基于 Dalvik 操作码序列的轻量级安卓恶意软件检测
LTAChecker: Lightweight Android Malware Detection Based on Dalvik Opcode Sequences using Attention Temporal Networks 摘要: Android 应用程序已成为黑客攻击的主要目标。安卓恶意软件检测是一项关键技术,对保障网络安全和阻止异常情况至关重要。…...
HTTPS链接建立的过程
HTTPS(HyperText Transfer Protocol Secure)建立链接的过程主要是通过TLS(Transport Layer Security)协议来实现的。HTTPS的链接建立过程可以分为以下几个步骤: 1. **客户端发起请求** - 客户端向服务器发送一个请求&…...
文档控件DevExpress Office File API v24.1 - 支持基于Unix系统的打印
DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库,不用安装Microsoft Office,就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…...
IP地址封装类(InetAddress类)
文章目录 前言一、IP地址是什么?二、IP地址封装类 1.常用方法2.实操展示总结 前言 当我们想要获取到通信对方的IP地址、主机地址等信息时,我们可以使用InetAddress类。InetAddress类在java的net包中。 一、IP地址是什么? IP地址 (Internet Pr…...
数据库设计规范化
在数据库设计中,尤其是在关系型数据库管理系统中,规范化(Normalization)是一种通过减少数据冗余和依赖关系来优化数据库表结构的过程。规范化可以确保数据的完整性和减少数据更新时的问题。规范化的过程通常遵循一系列标准或范式&…...
预约咨询小程序搭建教程,源码获取,从0到1完成开发并部署上线
目录 一、明确需求与规划功能 二、选择开发工具与模板 三、编辑小程序内容 四、发布与运营 五、部分代码展示 制作一个预约咨询小程序,主要可以分为以下几个步骤: 一、明确需求与规划功能 明确需求: 1.确定小程序的服务对象…...
leetcode217. 存在重复元素,哈希表秒解
leetcode217. 存在重复元素 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。 示例 1: 输入:nums [1,2,3,1] 输出:true 示例 2&#x…...
QT:QString 支持 UTF-8 编码吗?
在 Qt 中,字符串的处理主要依赖于 QString 类。QString 内部并不是直接使用 UTF-8 编码来存储数据的。相反,QString 使用 Unicode(特别是 UTF-16)来存储文本,以支持多语言环境的国际化应用。这种设计使得 QString 能够…...
我主编的电子技术实验手册(13)——电磁元件之继电器
本专栏是笔者主编教材(图0所示)的电子版,依托简易的元器件和仪表安排了30多个实验,主要面向经费不太充足的中高职院校。每个实验都安排了必不可少的【预习知识】,精心设计的【实验步骤】,全面丰富的【思考习…...
odoo from样式更新
.xodoo_form {.o_form_sheet {padding-bottom: 0 !important;border-style: solid !important;border-color: white;}.o_inner_group {/* 线框的样式 *//*--line-box-border: 1px solid #666;*//*box-shadow: 0 1px 0 #e6e6e6;*/margin: 0;}.grid {display: grid;gap: 0;}.row …...
Oracle(52)分区表有哪些类型?
分区表在Oracle数据库中主要分为以下几种类型: 范围分区(Range Partitioning)列表分区(List Partitioning)哈希分区(Hash Partitioning)组合分区(Composite Partitioning࿰…...
大黄蜂能飞的起来吗?
Bumblebee argument 虽然早期的空气动力学证明大黄蜂不能飞行——因为体重太重,翅膀太薄,但大黄蜂并不知道,所以照飞不误。 背景 在20世纪初,科学家们通过研究发现,大黄蜂的身体与翼展的比例失调,按照…...
虹科新品 | PDF记录仪新增蓝牙®接口型号HK-LIBERO CL-Y
新品发布!HK-LIBERO CE / CH / CL产品家族新增蓝牙接口型号HK-LIBERO CL-Y! PDF记录仪系列新增蓝牙接口型号 HK-LIBERO CL-Y HK-LIBERO CE、HK-LIBERO CH和HK-LIBERO CL,虹科ELPRO提供了一系列高品质的蓝牙(BLE)多用途…...
Bytebase 2.22.1 - SQL 编辑器展示更丰富的 Schema 信息
🚀 新功能 SQL 编辑器直接展示表,视图,函数,存储过程等各种 Schema 详情。OpenAI 功能进入社区版(免费),现在您可以通过配置自有 OpenAI key 在 SQL 编辑器中启用自然语言转 SQL 功能。支持在 …...
SQL Server Management Studio的使用
之前在 https://blog.csdn.net/fengbingchun/article/details/140961550 介绍了在Windows10上安装SQL Server 2022 Express和SSMS,这里整理下SSMS的简单使用: SQL Server Management Studio(SSMS)是一种集成环境,提供用于配置、监视和管理SQL…...
Python 爬虫项目实战一:抖音视频下载与网易云音乐下载
一、项目背景 随着互联网的发展,爬虫技术在数据采集和资源获取中发挥着重要作用。本文将以实际案例为例,使用Python语言实现两个热门的爬虫项目:抖音视频文件下载和网易云音乐下载。通过这些实例,读者可以了解如何利用Python编写…...
CAMDS=中国汽车MDS
1、定义和缩写 MSDS(材料安全数据表, Material Safety Data Sheets),德语为SDB(Sicherheitsdatenbltter),是一种传达材料和混合物安全相关信息的工具,包括来自供应链和下游用户相关材料安全报告的信息。它们旨在为专业用户提供使用这些物质和制剂的必要信息和处理建议,…...
【Golang 面试 - 进阶题】每日 3 题(十七)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...
AD09 PCB设计技巧与实战经验分享
1. PCB设计基础与AD09软件概述作为一名从业十年的硬件工程师,我使用Altium Designer(简称AD)完成了近百个PCB设计项目,从简单的双面板到复杂的八层板都有涉及。AD09虽然是比较早期的版本,但其核心功能已经非常完善&…...
Blender3mfFormat插件全攻略:从安装配置到3D打印工作流优化
Blender3mfFormat插件全攻略:从安装配置到3D打印工作流优化 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat Blender3mfFormat插件是一款专为Blender设计的3MF…...
改进蚁群算法结合Dijkstra与MAKLINK图理论实现二维空间最优路径规划
【改进蚁群算法】/蚁群算法/Dijkstra算法/遗传算法/人工势场法实现二维/三维空间路径规划 本程序为改进蚁群算法Dijkstra算法MAKLINK图理论实现的二维空间路径规划 算法实现: 1)基于MAKLINK图理论生成地图,并对可行点进行划分; 2…...
STM32F103C8T6用软件IIC驱动SGP30传感器,手把手教你搞定室内空气质量监测
STM32F103C8T6软件IIC驱动SGP30传感器实战指南 在智能家居和健康监测领域,空气质量检测正成为越来越受关注的技术方向。本文将带你从零开始,使用STM32F103C8T6这款性价比极高的MCU,通过软件模拟I2C接口驱动SGP30空气质量传感器,构…...
AI赋能仿真:借助快马平台让ExtendSim模型学会智能预测与动态调整
今天想和大家分享一个很有意思的实践:如何用AI给传统仿真模型加点"智能"。最近在做一个服务系统的仿真项目,发现顾客等待行为其实很复杂——不同人的耐心程度差异很大,传统仿真很难准确模拟这种动态变化。于是尝试用机器学习来优化…...
为你的项目量身定制,基于快马ai生成openclaw实战集成安装方案
最近在做一个图像处理相关的项目,需要在Ubuntu服务器上集成OpenClaw来处理图像数据,同时还要和OpenCV协同工作。整个过程踩了不少坑,今天就把我的实战经验分享给大家,特别是如何利用InsCode(快马)平台来快速生成定制化的安装方案。…...
阶跃星辰 GUI-MCP 解读---(2)---决策层
本文是第二篇,主要是介绍决策层,本层在任何情况下(是/非MCP)都会用到。因为是反推解读,而且时间有限,所以可能会有各种错误,还请大家不吝指出。0x01 LocalServerLocalServer 是本地 GUI Agent 服…...
Mem Reduct终极指南:一键释放内存,让你的Windows电脑飞起来
Mem Reduct终极指南:一键释放内存,让你的Windows电脑飞起来 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitcode.com/gh_mirrors/me/m…...
如何精准控制绝对定位元素的垂直位置(避免蓝条错位)
本文详解如何通过修正 CSS position: absolute 的定位属性,解决蓝色导航条在页面中随机错位的问题,核心是正确使用 top 或 bottom 而非混用导致布局失控。 本文详解如何通过修正 css position: absolute 的定位属性,解决蓝色导航条在页面…...
别再只调参了!用Open3D搞定点云凹凸检测,从数学原理到Python代码的保姆级避坑指南
点云凹凸检测实战:从数学本质到Open3D高效实现 点云处理中的凹凸缺陷检测一直是工业质检、三维重建等领域的核心难题。很多工程师习惯性地把问题归结为"参数没调好",却忽略了背后的数学本质和算法选择逻辑。本文将带您跳出调参陷阱࿰…...
