当前位置: 首页 > news >正文

GO随想:GO的并发等待

协程并发等待技术——WaitGroup 类型和 errgroup 包

waitgroup 

阻塞等待多个并发任务执行完成。WaitGroup 类型主要包含下面几个方法。

func (wg *WaitGroup) Add(delta int)
func (wg *WaitGroup) Done()
func (wg *WaitGroup) Wait()

第一个是 Add 方法,在任务运行之前,需要调用 Add 方法,用于设置需要等待完成的任务数,Add 方法传进去的数值之和,需要和任务数相等。

第二个是 Done 方法,每个任务完成时,需要调用 Done 方法,用于告知 WaitGroup 对象已经有一个任务运行完成。

第三个是 Wait 方法,当需要等待所有并发任务完成时,调用 Wait 方法,用于阻塞主协程。

 

import ("sync"
)var urls = []string{"http://www.golang.org/","http://www.google.com/","http://www.somestupidname.com/",
}func TestWaitGroup(t *testing.T) {// 创建WaitGroupwg := sync.WaitGroup{}results := make([]string, len(urls))for index, url := range urls {url := urlindex := index// 在创建协程执行任务之前,调用Add方法wg.Add(1)go func() {// 任务完成后,调用Done方法defer wg.Done()// Fetch the URL.resp, err := http.Get(url)if err != nil {return}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {return}results[index] = string(body)}()}// 主协程阻塞,等待所有的任务执行完成wg.Wait()
}

errgroup 包

可以在主协程中获取并发任务错误信息 

import ("golang.org/x/sync/errgroup"
)func TestErrHandle(t *testing.T) {results := make([]string, len(urls))// 创建Group类型g := new(errgroup.Group)for index, url := range urls {// Launch a goroutine to fetch the URL.url := urlindex := index// 调用Go方法g.Go(func() error {// Fetch the URL.resp, err := http.Get(url)if err != nil {return err // 返回错误}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {return err // 返回错误}results[index] = string(body)return nil})}// Wait for all HTTP fetches to complete.// 等待所有任务执行完成,并对错误进行处理if err := g.Wait(); err != nil {fmt.Println("Failured fetched all URLs.")}
}

 第一步,我们要创建 Group 类型的对象。

第二步,在 Group 的 Go 方法中传入那些需要并发运行的函数。特别需要注意的是,这些传入的函数必须将错误返回。

第三步,也是最后一步,在主协程中,我们需要调用 Group 对象的 Wait 方法。通过这一调用,主协程将会阻塞等待,直至所有通过 Go 方法传入的任务都执行完毕。并且,在任务完成后,我们还能够对 Wait 方法所返回的错误进行处理。

func TestLimitGNum(t *testing.T) {results := make([]string, len(urls))// 用WithContext函数创建Group对象eg, ctx := errgroup.WithContext(context.Background())// 调用SetLimit方法,设置可同时运行的最大协程数eg.SetLimit(2)for index, url := range urls {url := urlindex := index// 调用Go方法eg.Go(func() error {select {case <-ctx.Done(): // select-done模式取消运行return errors.New("task is cancelled")default:// 并发获取urlresp, err := http.Get(url)if err != nil {return err // 返回错误}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {return err // 返回错误}results[index] = string(body)return nil}})}// 等待所有任务执行完成,并对错误进行处理if err := eg.Wait(); err != nil {fmt.Println("Failured fetched all URLs.")}
}

 errorGroup 包中的结构体

type token struct{}type Group struct {cancel func(error) // 这个作用是為了前面說的 WithContext 而來的wg sync.WaitGroup // errGroup底层的阻塞等待功能,就是通过WaitGroup实现的sem chan token // 用于控制最大运行的协程数err     error // 最后在Wait方法中返回的errorerrOnce sync.Once // 用于安全的设置err
}

总结:

1. WaitGroup类型是Golang的基础并发类型,用于阻塞等待多个并发任务执行完成,包含Add、Done和Wait方法。

2. errgroup包是Golang提供的并发扩展库,对WaitGroup进行了封装,在并发等待的基础功能上提供了错误处理和任务取消功能。

3. Group类型的Go方法用于传入具有错误返回值的函数类型,Wait方法会阻塞等待所有传入Go方法的函数全部运行完毕,并且在任务完成后能够对错误进行处理。

4. 任务取消功能通过WithContext函数创建Group对象,传入Go方法的函数需要实现select-done模式,利用context来停止所有相关任务。

5. errgroup包还可以限制同时并发运行的最大协程数,通过SetLimit方法设置可同时运行的最大协程数,达到最大协程数时会阻塞创建新协程运行任务。

相关文章:

GO随想:GO的并发等待

协程并发等待技术——WaitGroup 类型和 errgroup 包 waitgroup 阻塞等待多个并发任务执行完成。WaitGroup 类型主要包含下面几个方法。 func (wg *WaitGroup) Add(delta int) func (wg *WaitGroup) Done() func (wg *WaitGroup) Wait() 第一个是 Add 方法&#xff0c;在任务运…...

kubernetes第五天

1.容器的健康检查Probe&#xff08;探针&#xff09;之readinessProbe就绪探针 1.exec方式检查 #通过rc资源创建了三个pod,然后使用services资源&#xff0c;对外提供三个pod的容器的访问入口。 apiVersion: v1 kind: ReplicationController metadata:name: web-rc-readlinepr…...

扩散模型论文概述(三):Stability AI系列工作【学习笔记】

视频链接&#xff1a;扩散模型论文概述&#xff08;三&#xff09;&#xff1a;Stability AI系列工作_哔哩哔哩_bilibili 本期视频讲的是Stability AI在图像生成的工作。 同样&#xff0c;第一张图片是神作&#xff0c;总结的太好了&#xff01; 介绍Stable Diffusion之前&…...

JVM调优,参数在哪里设置的?

JVM调优&#xff0c;参数在哪里设置的&#xff1f; 在Java应用程序中&#xff0c;JVM&#xff08;Java Virtual Machine&#xff09;的调优通常通过设置JVM启动参数来实现。这些参数可以控制JVM的内存分配、垃圾回收策略、线程管理、性能优化等方面。 1. JVM参数的位置 JVM参…...

2024年最新Stable Diffusion 新手入门教程,安装使用及模型下载

一、安装要求&#xff1a; ① 操作系统&#xff1a;Windows10以后的系统 ② CPU&#xff1a;不做强制性要求 ③ 内存&#xff1a;推荐8G以上 ④ 显卡&#xff1a;必须是Nvidia的独立显卡&#xff0c;显存最低4G&#xff0c;推荐20系以后&#xff1b;A卡、核显只能用CPU跑 …...

Ubuntu 20.04安装gcc

一、安装GCC 1.更新包列表 user596785154:~$ sudo apt update2.安装gcc user596785154:~$ sudo apt install gcc3.验证安装 user596785154:~$ gcc --version二 编译C文件 1.新建workspace文件夹 user596785154:~$ mkdir workspace2.进入workspace文件夹 user596785154:~…...

IT运维的365天--024 闲置路由器关闭了dhcp,如何知道它的IP是啥

有时候各种原因&#xff0c;我们关闭了路由器的Dhcp&#xff0c;比如需要获取的无线IP和有线同一个网段的情况。时间久了&#xff0c;如果没做标记&#xff0c;大部分时候就会忘了路由器原来设置的是什么IP&#xff0c;没有路由器的对应IP&#xff0c;自然也无法进路由器后台去…...

kaggle竞赛:纽约出租车行程时间NYC Taxi Trip Duration

1.引言 作为一名&#xff08;坦白说有点懒的&#xff09;图像处理方向的研究生&#xff0c;说实话最近新开一个坑&#xff0c;可能是因为要寒假了比较无聊&#xff0c;这次带来的系列是kaggle数据处理竞赛的经典例题&#xff1a;纽约出租车行程时间问题。希望大家多多支持&…...

Freemarker模板进行判空

文章目录 freemarker判断对象是否为null使用 ?? 操作符使用 ?has_content 内建函数直接使用 ! 操作符取反 freemarker判断列表是否为空 freemarker判断对象是否为null 在 FreeMarker 模板引擎中&#xff0c;你可以使用内建的指令和条件判断来检测一个对象是否为 null。Free…...

C++ const关键字(八股总结)

作用 const修饰符用来定义常量&#xff0c;具有不可变性。 修饰变量&#xff0c;说明该变量不可以被改变&#xff1b;修饰指针&#xff0c;分为指向常量的指针&#xff08;pointer to const&#xff09;和自身是常量的指针&#xff08;常量指针&#xff0c;const pointer&…...

Linux 清楚历史命令

在 Linux 中&#xff0c;执行完命令后&#xff0c;如果你想清除终端屏幕上的内容&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用 clear 命令 clear 是 Linux 中最常用的清除屏幕命令。它会将终端屏幕清空&#xff0c;并将光标移动到屏幕左上角。 bash clear 2. 使用快…...

服务器双网卡NCCL通过交换机通信

1、NCCL变量设置 export CUDA_DEVICE_MAX_CONNECTIONS1 export NCCL_SOCKET_IFNAMEeno2 export NCCL_IB_DISABLE0 #export NCCL_NETIB export NCCL_IB_HCAmlx5_0,mlx5_1 export NCCL_IB_GID_INDEX3 export NCCL_DEBUGINFOGPUS_PER_NODE4MASTER_ADDR192.168.1.2 MASTER_PORT600…...

Redis哨兵(sentinel)

是什么 吹哨人巡查监控后台master主机是否故障&#xff0c;如果故障了根据投票数自动将某一个从库转换为新主库&#xff0c;继续对外服务 哨兵的作用 1、监控redis运行状态&#xff0c;包括master和slave 2、当master down机&#xff0c;能自动将slave切换成新master 能干嘛…...

小白学Pytorch

小白学Pytorch 发现一个比较好的教程&#xff0c;对于自己来说比较合适&#xff0c;适合从零开始的教程。 1、搭建一个简单的网络 https://www.cnblogs.com/PythonLearner/p/13587092.html 搭建网络这步说的比较清楚&#xff1a; 我们使用nn包中的Sequential搭建网络&#…...

ros2笔记-2.5.3 多线程与回调函数

本节体验下多线程。 python示例 在src/demo_python_pkg/demo_python_pkg/下新建文件&#xff0c;learn_thread.py import threading import requestsclass Download:def download(self,url,callback):print(f线程&#xff1a;{threading.get_ident()} 开始下载&#xff1a;{…...

第5章:Go语言错误处理和异常

第5章&#xff1a;Go语言错误处理和异常 5.1 错误类型基础 5.1.1 error接口 // error接口定义 type error interface {Error() string }// 自定义错误 type CustomError struct {Message stringCode int }func (e *CustomError) Error() string {return fmt.Sprintf(&quo…...

题库刷题知识点总结

算法与机器学习相关 支持向量机&#xff1a;是一种有监督的机器学习算法&#xff0c;用于分类和回归任务。它通过寻找一个最优超平面来将不同类别的数据点分开&#xff0c;最大化两类数据点到超平面的间隔&#xff0c;具有良好的泛化能力和抗噪声能力。机器学习&#xff1a;是…...

GraphRAG:LLM之Graphrag接入milvus

前言 微软目前的graphrag更像个demo&#xff0c;数据量大的时候不是很友好的啊&#xff0c;所以将milvus接入了graphrag&#xff0c;看完这篇文章&#xff0c;其他数据库接入应该也没问题 注&#xff1a;这篇文章只是在search的时候接入进来&#xff0c;index过程或者说整个流…...

adb使用及常用命令

目录 介绍 组成 启用adb调试 常用命令 连接设备 版本信息 安装应用 卸载应用 文件操作 日志查看 屏幕截图和录制 设备重启 端口转发 调试相关 设置属性 设备信息查询 获取帮助 模拟输入 介绍 adb全称为 Android Debug Bridge(Android调试桥)&#xff0c;是 A…...

omnipeek分析beacon帧

omnipeek查询设备发送beacon时同一信道两个beacon发送间隔 目录 用例要求分析抓包数据 1.用例要求 Beacon帧发送频率符合规范要求。参数-【同一个信道两个beacon发送间隔不能超过100ms】 2.分析抓包数据 打开becon.pkt文件&#xff08;用omnipeek工具提前抓取包&#xff09…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...