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

【从零单排Golang】第十三话:使用WaitGroup等待多路并行的异步任务

在后端开发当中,经常会遇到这样的场景:请求给了批量的输入,对于每一个输入,我们都要给外部发请求等待返回,然后才能继续其它自己的业务逻辑。在这样的case下,如果每一个输入串行处理的话,那么很大一部分时间都会损耗在给外部发请求这个环节,因此我们会希望把这些请求放到各个goroutine里异步执行,等待批量执行完成之后再继续后面的逻辑。这个时候,我们就可以用到这个东西:sync.WaitGroup

WaitGroup提供了增减计数以及阻塞等待计数归零的线程安全接口。当主goroutine增加计数并等待的时候,子goroutine的逻辑中若引用了一个WaitGroup实例的话,也可以在结束(defer)的时候去减少计数,这样当主goroutine自旋等待计数归零时,等待的逻辑就返回了,就继续后面的内容。整体上,就达到了等待多路并行的异步任务这一效果。

一个典型的代码案例如下:

func TestWaitGroup(t *testing.T) {var wg sync.WaitGroupstartTime := time.Now()for i := 0; i < 5; i++ {n := i + 1sleepTime := time.Duration(n) * time.Secondwg.Add(1)go func() {defer wg.Done()t.Logf("task %d started", n)time.Sleep(sleepTime)t.Logf("task %d ended", n)}()}t.Logf("waiting for all tasks done...")wg.Wait()endTime := time.Now()t.Logf("all tasks done! elapsed time: %v", endTime.Sub(startTime))
}

整个逻辑很简单,我们起了5个任务,每个任务分别sleep上1到5秒。主goroutine此时在每个任务开始前,给WaitGroup实例wg加上1个计数,而在子goroutine里,defer地调用wg.Done减少计数。主goroutine起完任务之后,直接调用wg.Wait自选等待。这样5s后等所有任务Done,主goroutine就会接下来打印消耗时间的日志信息了。

打印的内容如下:

=== RUN   TestWaitGroupwg_test.go:26: waiting for all tasks done...wg_test.go:21: task 5 startedwg_test.go:21: task 1 startedwg_test.go:21: task 2 startedwg_test.go:21: task 3 startedwg_test.go:21: task 4 startedwg_test.go:23: task 1 endedwg_test.go:23: task 2 endedwg_test.go:23: task 3 endedwg_test.go:23: task 4 endedwg_test.go:23: task 5 endedwg_test.go:29: all tasks done! elapsed time: 5.0015089s
--- PASS: TestWaitGroup (5.00s)
PASS

WaitGroup的用法非常简单,但这里注意的是,实际遇到这种编程场景,一般会涉及到多任务运行结果收集还有程序异常处理相关的内容。因此,像recover或者select超时等一些子goroutine任务异常处理的逻辑,可能视实际情况都得配合加上。

http://www.lryc.cn/news/112710.html

相关文章:

  • WSL2安装CentOS7和CentOS8
  • 不平衡电网条件下基于变频器DG操作的多目标优化研究(Matlab代码Simulink实现)
  • 【Leetcode】(自食用)简单题||单词数
  • C语言代码的x86-64汇编指令分析过程记录
  • 基于springboot+vue的房屋租赁系统(前后端分离)
  • Python文件读写操作详解:从基础到高级
  • ThreadLocal基本介绍
  • ffmpeg源码编译成功,但是引用生成的静态库(.a)报错,报错位置在xxx_list.c,报错信息为某变量未定义
  • 2023爱分析·信创云市场厂商评估报告:中国电子云
  • 网络安全学习笔记——XFF攻击流程
  • 微信小程序阻止用户返回上一页,并弹窗给用户确定是否要返回上一页
  • LangChain+ChatGLM整合LLaMa模型(二)
  • 【NLP】训练chatglm2的评价指标BLEU,ROUGE
  • java+springboot+mysql员工工资管理系统
  • FL Studio Producer Edition 21 v21.0.3 Build 3517 Windows/mac官方中文版
  • 探索Python数据容器之乐趣:列表与元组的奇妙旅程!
  • Python自动化实战之使用Pytest进行API测试详解
  • TCP的三次握手以及四次断开
  • 目标检测YOLO实战应用案例100讲-基于视觉与激光雷达信息融合的智能车辆目标检测研究
  • Day 22 C++ STL常用容器——string容器
  • 使用Socket实现UDP版的回显服务器
  • 【MCU学习】GD32F427VG开发
  • Acwing.877 扩展欧几里得算法
  • 基于自组织竞争网络的患者癌症发病预测(matlab代码)
  • golang mongodb
  • docker中的jenkins去配置sonarQube
  • 企业如何实现自己的AI垂直大模型
  • Maven可选依赖和排除依赖简单使用
  • “深入探索JVM:Java虚拟机的工作原理解析“
  • Prometheus-各种exporter