go语言中使用WaitGroup和channel实现处理多线程问题

WaitGroup

背景

如果将一个任务分为任意个小任务,并且不关心小任务的执行顺序,并且希望等待全部的小任务执行完成后再去操作后面的逻辑,那我推荐你用sync.WaitGRoup

使用方法

比如,有一个任务需要执行 3 个子任务,那么可以这样写:

package mainimport ("fmt""sync"
)func main() {// 定义信号量var wg sync.WaitGroup// wg 添加任务数量wg.Add(3)// 创建三个携程处理wggo func(i int, wg *sync.WaitGroup) {// 提前定义结束defer wg.Done()fmt.Printf("执行任务%d\n", i)}(1, &wg)go func(i int, wg *sync.WaitGroup) {// 提前定义结束defer wg.Done()fmt.Printf("执行任务 %d\n", i)}(2, &wg)go func(i int, wg *sync.WaitGroup) {// 提前定义结束defer wg.Done()fmt.Printf("执行任务 %d\n", i)}(3, &wg)// 等待所有携程执行完毕fmt.Println("等待所有任务执行中....")wg.Wait()fmt.Println("所有任务执行完了....")
}

踩坑点避免

1.调用时应该调用&wg而不是wg(调用引用)

// 正确
go handlerTask1(&wg)// 错误
go handlerTask1(wg)

2.确保wg.Add()应该在wg.Wait()之前执行

 // 错误
var wg sync.WaitGroupgo handlerTask1(&wg)wg.Wait()...func handlerTask1(wg *sync.WaitGroup) {wg.Add(1)defer wg.Done()fmt.Println("执行任务 1")
}

3.注意 wg.Add() 和 wg.Done() 的计数器保持一致

小结

sync.WaitGroup 使用起来比较简单,一定要注意不要踩到坑里。

其实 sync.WaitGroup 使用场景比较局限,仅适用于等待全部子任务执行完毕后,再进行下一步处理,如果需求是当第一个子任务执行失败时,通知其他子任务停止运行,这时 sync.WaitGroup 是无法满足的,需要使用到通知机制(channel)。

Channel

由于时间原因,在这里只简单讲一下Channel的作用吧

1.作为锁保证多协程执行时线程安全

2.控制并发数量

https://juejin.cn/post/7175028144812851237

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

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

相关文章

Raw Socket(一)实现TCP三次握手

实验环境: Windows物理机:192.168.1.4 WSL Ubuntu 20.04.6 LTS:172.19.32.196 Windows下的一个http服务器:HFS,大概长这个样子: 客户端就是Ubuntu,服务端就是这个…

收银系统源码-线上商城预售功能

1.功能描述 预售:智慧新零售收银系统,线上商城营销插件之一,商品出售时可设置以支付定金或全款的方式提前预售,门店按订单量备货,降低压货成本; 2.适用场景 易损商品提前下单备货,如水果生鲜…

【算法笔记自学】第 5 章 入门篇(3)——数学问题

5.1简单数学 #include <cstdio> #include <algorithm> using namespace std; bool cmp(int a,int b){return a>b; } void to_array(int n,int num[]){for(int i0;i<4;i){num[i]n%10;n /10;} } int to_number(int num[]){int sum0;for(int i0;i<4;i){sumsu…

C++ Lambda表达式第二篇, Lambda表达式

C Lambda表达式 Lambda 捕获含有模板参数的Lambda表达式无模板参数的Lambda表达式 Lambda 捕获 captures是零个或多个捕获的逗号分隔列表&#xff0c;可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是 &&#xff0c;…

Kylin系列(二)架构解析:深入理解 Kylin 的架构设计

目录 1. 引言 2. Kylin 的基本概念 2.1 预计算 2.2 多维数据集&#xff08;Cube&#xff09; 2.3 维度和度量 3. Kylin 的架构设计 3.1 数据源 3.2 数据建模 3.2.1 星型模型 3.2.2 雪花模型 3.3 多维数据集构建 3.3.1 数据导入 3.3.2 维度和度量计算 3.3.3 存储优…

AI微电影制作教程:轻松打造高清小人国画面

AI微电影作为一种新兴的视频内容形式&#xff0c;以其独特的视觉效果和制作技术在各大视频平台上取得了显著的流量表现。 2. AI微电影的特点 2.1 高清画质与流畅动作&#xff1a;AI微电影以其高分辨率和流畅的动作给观众带来优质的视觉体验。 2.2 微缩画面效果&#xff1a;独…

大数据面试题之Presto[Trino](6)

如何诊断Presto查询慢的问题&#xff1f; 诊断Presto查询慢的问题通常需要一个系统化的方法&#xff0c;结合监控、日志分析、查询优化策略和系统配置调整等多个方面。以下是一些具体的步骤和建议&#xff1a;1、查看Presto Dashboard&#xff1a; 登录Presto的Web UI&#xf…

WebKit 入门案例教程

WebKit 的基本概念 1.什么是 WebKit&#xff1f;&#xff1a;WebKit 是一个开源的浏览器引擎&#xff0c;用于渲染 HTML、CSS 和 JavaScript 等内容。 2.WebKit 的组件&#xff1a;WebKit 的组件包括 HTML 解析器、CSS 解析器、JavaScript 引擎、布局引擎等。 3.WebKit 的应用…

用 adb 来模拟手机插上电源和拔掉电源的情形

实用的 ADB 命令 要模拟手机从 USB 充电器上拔掉的情形&#xff0c;你可以使用&#xff1a; adb shell dumpsys battery set usb 0或者&#xff0c;如果你使用的是 Android 6.0 或更高版本的设备&#xff0c;你可以使用&#xff1a; adb shell dumpsys battery unplug要重新…

使用Docker、Docker-compose部署单机版达梦数据库(DM8)

安装前准备 Linux Centos7安装&#xff1a;https://blog.csdn.net/andyLyysh/article/details/127248551?spm1001.2014.3001.5502 Docker、Docker-compose安装&#xff1a;https://blog.csdn.net/andyLyysh/article/details/126738190?spm1001.2014.3001.5502 下载DM8镜像 …

三种 FRR 技术演进 LFA、rLFA、Ti-LFA

FRR&#xff1a;Fast ReRoute 快速重路由&#xff0c;是为最大程度地减少流量损失&#xff0c;路由器预先安装一条备份路径&#xff0c;当故障发生的时候&#xff0c;由邻近故障点的路由器&#xff08;PLR&#xff1a;Point of Local Repair&#xff0c;本地修复节点&#xff0…

在Java Web项目中遇到过哪些技术难题以及如何解决的

在Java Web项目中&#xff0c;开发者可能会遇到多种技术难题。这些难题可能涉及框架使用、性能优化、安全性、数据库交互、前后端交互等多个方面。以下是一些常见的技术难题及其可能的解决方案&#xff1a; 1. 框架使用问题 难题&#xff1a; Spring Boot、Spring MVC等框架…

自动控制:前馈控制

自动控制&#xff1a;前馈控制 前馈控制是一种在控制系统中通过预先计算和调整输入来应对已知扰动或变化的方法。相比于反馈控制&#xff0c;前馈控制能够更快速地响应系统的变化&#xff0c;因为它不依赖于系统输出的反馈信号。前馈控制的应用在工业过程中尤为广泛&#xff0…

银河麒麟(V10SP1)-arm版交叉编译-qt-5.12.12源码

前言 确实是编译出来了qtbase库和qtwebengine库&#xff0c;如果按照文章没有操作出来有两种情况 (1) 读者阅读不仔细 (2) 我后期记录整理时写错了 不完美之处和遗留问题 读者阅读前须知 1. 最后发现没有生成libqxcb库文件,如果在国产化系统上执行qt程序时依赖的是自己编译…

element-ui输入框如何实现回显的多选样式?

废话不多说直接上效果&#x1f9d0; 效果图 <template><div><el-form:model"params"ref"queryForm"size"small":inline"true"label-width"68px"><el-form-item label"标签" prop"tag&q…

基于java+springboot+vue实现的仓库管理系统(文末源码+lw+ppt)23-499

第1章 绪论 伴随着信息社会的飞速发展&#xff0c;仓库管理所面临的问题也一个接一个的出现&#xff0c;所以现在最该解决的问题就是信息的实时查询和访问需求的问题&#xff0c;以及如何利用快捷便利的方式让访问者在广大信息系统中进行查询、分享、储存和管理。这对我们的现…

微积分-导数5(链式法则)

链式法则 假设你想求下面的函数的导数 f ( x ) x 2 1 f(x) \sqrt{x^2 1} f(x)x21 ​ 之前学到的微分法则没求 F ′ ( x ) F(x) F′(x)。 我们观察到 F F F 是一个复合函数。实际上&#xff0c;如果我们令 y f ( u ) u y f(u) \sqrt{u} yf(u)u ​ 并且 u g ( x ) …

Oracle PL / SQL运算符

连接运算符 串联运算符||将一个字符串操作数附加到另一个。 每个字符串可以是CHAR&#xff0c;VARCHAR2&#xff0c;CLOB。 如果任一个字符串是CLOB&#xff0c;则结果是临时CLOB; 否则&#xff0c;它是一个VARCHAR2值。 下面的代码连接运算符。 DECLARE x VARCHAR2(4) : …

Golang 类型断言+反射+序列化

类型断言 什么是类型断言 由于多态的存在&#xff0c;接口变量不知道其指向的具体类型&#xff0c;如果需要转为具体类型&#xff0c;则需要使用类型断言 类型断言语法 接口变量名.(具体类型) // 此处变量必须为 interface 类型类型断言返回值 x : 变量名.(具体类型) // 如…

【第三版 系统集成项目管理工程师】第4章 信息系统架构

持续更新。。。。。。。。。。。。。。。 【第三版】系统集成项目管理工程师 考情分析4.1架构基础4.1.1指导思想&#xff08;非重点&#xff09; P1364.1.2设计原则&#xff08;非重点&#xff09; P1364.1.3建设目标&#xff08;非重点&#xff09; P1374.1.4总体框架 P138练习…