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

Golang并发-Go优雅的退出程序(同步等待组 sync.WaitGroup)

文章目录

  • Golang并发:并发协程的优雅退出
    • 同步等待组 sync.WaitGroup
    • 示例
    • sync.WaitGroup 实现原理
    • 参考

Golang并发:并发协程的优雅退出

同步等待组 sync.WaitGroup

Go语言中除了可以使用通道(channel)和互斥锁进行两个并发程序间的同步外,还可以使用等待组进行多个任务的同步,等待组可以保证在并发环境中完成指定数量的任务。

sync.WaitGroup对于Golang开发者来说并不陌生,其经常作为多协程之间同步的一种机制。

在实际使用Go协程实现并行应用时,可能会遇到这样场景:需要阻塞部分代码执行,直到其他协程成功执行之后才继续执行。

同步等待组(WaitGroups)就是要解决这类问题,阻塞应用直到同步等待组中的所有协程都成功执行。

等待组内部拥有一个计数器,计数器的值可以通过方法调用实现计数器的增加和减少。当我们添加了 N 个并发任务进行工作时,就将等待组的计数器值增加 N。每个任务完成时,这个值减 1。同时,在另外一个 goroutine 中等待这个等待组的计数器值为 0 时,表示所有任务已经完成。

首先调用同步等待组的Add(1)方法,设置需要等待协程数量, 然后再协程内部调用Done() 方法表明协程执行结束。

注意,需要确保再执行协程之前调用Add(1)方法。

WaitGroup 有三个方法,其中 Done() 调用了 Add(-1)。标准用法:
(1)启动 Go 程时调用 Add();
(2)在 Go 程结束时调用 Done();
(3)最后调用 Wait()。

WaitGroup 对外提供了3个接口:
在这里插入图片描述

示例

同时开三个协程去请求网页, 等三个请求都完成后才继续 Wait 之后的工作。

var wg sync.WaitGroup 
var urls = []string{ 
 "http://www.golang.org/", 
 "http://www.google.com/", 
 "http://www.somestupidname.com/", 
} 
for _, url := range urls { 
 // Increment the WaitGroup counter. 
 wg.Add(1) 
 // Launch a goroutine to fetch the URL. 
 go func(url string) { 
 // Decrement the counter when the goroutine completes. 
 defer wg.Done() 
 // Fetch the URL. 
 http.Get(url) 
 }(url) 
} 
// Wait for all HTTP fetches to complete. 
wg.Wait()

sync.WaitGroup 实现原理

sync.WaitGroup 实现原理
参考URL: https://www.jianshu.com/p/6cedae8c18a0
Golang package sync 剖析(二): sync.WaitGroup
链接:https://segmentfault.com/a/1190000021653777

参考

Golang并发:并发协程的优雅退出
参考URL: https://www.jianshu.com/p/79d27f200bcf
Go 协程的开启和退出
https://studygolang.com/articles/28457?fr=sidebar
Go语言等待组(sync.WaitGroup)
参考URL: http://c.biancheng.net/view/108.html

相关文章:

  • 520.检测大写字母
  • 分位数回归的求解
  • Hadoop 完全分布式(3.1.3)部署(清爽版)
  • 【.Net实用方法总结】 整理并总结文件和流、异步文件IO、处理IO错误
  • LeetCode力扣刷题——千奇百怪的排序算法
  • django基于python的疫情防控下医院人员调动系统--python-计算机毕业设计
  • 详解字符串比较函数:strcmp函数及其模拟实现
  • 【Linux】安装Tomcat以yum方式安装
  • 【羊了个羊】背后的计算机网络原理
  • 面试题--框架篇
  • 字节4面通过,我可以跟面试官要30K吗?
  • Python算法性能分析-时间复杂度
  • java 基本微信小程序的心理咨询服务系统 uniapp 小程序
  • JQ----事件
  • FPGA 20个例程篇:16.HDMI显示彩色风景图
  • C学习-枚举(九)
  • echarts花样作死的坑
  • js作用域和this的理解
  • MD5加密原理解析及OC版原理实现
  • MySQL几个简单SQL的优化
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Python 反序列化安全问题(二)
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • ucore操作系统实验笔记 - 重新理解中断
  • uni-app项目数字滚动
  • 程序员最讨厌的9句话,你可有补充?
  • 简单基于spring的redis配置(单机和集群模式)
  • 前端面试之CSS3新特性
  • 赢得Docker挑战最佳实践
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​ubuntu下安装kvm虚拟机
  • ​如何在iOS手机上查看应用日志
  • #DBA杂记1
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (多级缓存)缓存同步
  • ./configure,make,make install的作用
  • .“空心村”成因分析及解决对策122344
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .mysql secret在哪_MySQL如何使用索引
  • .NET gRPC 和RESTful简单对比
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • @Transactional 详解
  • [ C++ ] STL---string类的使用指南
  • [16/N]论得趣
  • [ACTF2020 新生赛]Include
  • [AndroidStudio]_[初级]_[修改虚拟设备镜像文件的存放位置]
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • [IDF]啥?
  • [IE技巧] IE 中打开Office文件的设置
  • [java]删除数组中的某一个元素
  • [JS]JavaScript 简介
  • [js]js设计模式小结
  • [LeetCode]284. Peeking Iterator(C++,类,暴力)
  • [one_demo_3]漩涡递增矩阵