Go语言中的同步原语:ErrGroup、Semaphore和SingleFlight

1. 并发基础

并发是同时发生多个计算或事件的能力。并发通常通过同时执行多个任务或进程来实现,这些任务或进程共享相同的资源(例如内存或处理器)。并发使用的基本机制被称为锁。在Go语言中,锁是一个类型变量,它包含一个内部计数器,用于跟踪已获取的锁的数量。当一个goroutine获取一个锁时,它会将计数器增加一;当一个goroutine释放一个锁时,它会将计数器减少一。

2. 同步原语

同步原语是一组特殊的变量或类型,用于在并发程序中协调goroutine之间的通信和同步。Go语言中提供了丰富的同步原语,包括互斥锁(mutex)、读写锁(RWMutex)、等待组(WaitGroup)、一次性锁(Once)、条件变量(Cond)、错误组(ErrGroup)、信号量(Semaphore)和单次调用(SingleFlight)。

3. ErrGroup

ErrGroup是一个同步原语,它允许一组goroutine并发地执行任务,并收集所有goroutine执行过程中发生的错误。ErrGroup包含一个内部错误列表,当任何一个goroutine在执行任务时发生错误,该错误将被添加到错误列表中。ErrGroup还提供了一个Wait方法,该方法将阻塞当前goroutine,直到所有goroutine都完成执行任务,或者发生错误。

package mainimport ("context""fmt""sync"
)func main() {// 创建一个错误组var eg sync.ErrGroup// 创建三个goroutine来并发地执行任务for i := 0; i < 3; i++ {i := ieg.Go(func() error {// 模拟任务执行if i == 2 {return fmt.Errorf("error occurred in goroutine %d", i)}return nil})}// 等待所有goroutine完成执行任务if err := eg.Wait(); err != nil {fmt.Println(err) // 输出:error occurred in goroutine 2}
}

在这个示例中,我们使用ErrGroup来收集三个goroutine执行过程中发生的错误。如果任何一个goroutine在执行任务时发生错误,该错误将被添加到错误列表中,并最终在Wait方法中被打印出来。

4. Semaphore

Semaphore是一个同步原语,它用于限制可以同时访问共享资源的goroutine数量。Semaphore包含一个内部计数器,该计数器表示可用的资源数量。当一个goroutine需要访问共享资源时,它必须先获取Semaphore,如果Semaphore的计数器大于0,则该goroutine可以访问共享资源,否则该goroutine将被阻塞,直到Semaphore的计数器大于0。当一个goroutine不再需要访问共享资源时,它必须释放Semaphore,以允许其他goroutine访问共享资源。

package mainimport ("context""fmt""sync"
)func main() {// 创建一个信号量,限制同时可以访问共享资源的goroutine数量为2sem := make(chan struct{}, 2)// 创建三个goroutine来并发地访问共享资源for i := 0; i < 3; i++ {i := igo func() {// 获取信号量sem <- struct{}{}// 模拟访问共享资源fmt.Println("Goroutine", i, "is accessing the shared resource.")time.Sleep(1 * time.Second)// 释放信号量<-sem}()}// 等待所有goroutine完成time.Sleep(3 * time.Second)
}

在这个示例中,我们使用Semaphore来限制同时可以访问共享资源的goroutine数量为2。当一个goroutine需要访问共享资源时,它必须先获取Semaphore,如果Semaphore的计数器大于0,则该goroutine可以访问共享资源,否则该goroutine将被阻塞,直到Semaphore的计数器大于0。

5. SingleFlight

SingleFlight是一个同步原语,它确保某个操作只会被执行一次。SingleFlight包含一个内部映射,该映射将操作的key映射到操作的结果。当一个goroutine需要执行某个操作时,它必须先检查SingleFlight的内部映射中是否已经存在该操作的结果。如果存在,则该goroutine直接返回该结果,否则该goroutine将执行该操作,并将结果存储在SingleFlight的内部映射中,以便其他goroutine可以直接返回该结果。

package mainimport ("context""fmt""sync"
)var sf sync.SingleFlightfunc main() {// 定义一个需要执行的操作fn := func() (int, error) {// 模拟执行操作return 100, nil}// 并发地执行该操作10次for i := 0; i < 10; i++ {go func() {// 获取操作的结果result, err := sf.Do("key", fn)if err != nil {fmt.Println(err)return}fmt.Println("Result:", result)}()}// 等待所有goroutine完成time.Sleep(1 * time.Second)
}

在这个示例中,我们使用SingleFlight来确保fn函数只会被执行一次。当一个goroutine需要执行fn函数时,它必须先检查SingleFlight的内部映射中是否已经存在fn函数的结果。如果存在,则该goroutine直接返回该结果,否则该goroutine将执行fn函数,并将结果存储在SingleFlight的内部映射中,以便其他goroutine可以直接返回该结果。

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

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

相关文章

ubuntu nginx安装部署

上传nginx-1.18.0.tar.gz mv nginx-1.18.0.tar.gz /usr/local/ #解压 tar -zxvf nginx-1.18.0.tar.gz #安装 cd nginx-1.18.0 #安装依赖包apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgeoip-dev openssl libgd…

【开源】基于JAVA+Vue+SpringBoot的医院门诊预约挂号系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 功能性需求2.1.1 数据中心模块2.1.2 科室医生档案模块2.1.3 预约挂号模块2.1.4 医院时政模块 2.2 可行性分析2.2.1 可靠性2.2.2 易用性2.2.3 维护性 三、数据库设计3.1 用户表3.2 科室档案表3.3 医生档案表3.4 医生放号…

【目标检测】YOLOv5算法实现(七):模型训练

本系列文章记录本人硕士阶段YOLO系列目标检测算法自学及其代码实现的过程。其中算法具体实现借鉴于ultralytics YOLO源码Github&#xff0c;删减了源码中部分内容&#xff0c;满足个人科研需求。   本系列文章主要以YOLOv5为例完成算法的实现&#xff0c;后续修改、增加相关模…

2023一带一路暨金砖国家技能发展与技术创新大赛“网络安全”赛项省选拔赛样题卷①

2023金砖国家职业技能竞赛"网络安全" 赛项省赛选拔赛样题 2023金砖国家职业技能竞赛 省赛选拔赛样题第一阶段&#xff1a;职业素养与理论技能项目1. 职业素养项目2. 网络安全项目3. 安全运营 第二阶段&#xff1a;安全运营项目1. 操作系统安全配置与加固任务一Linux …

机器学习和深度学习检测网络安全课题资料:XSS、DNS和DGA、恶意URL、webshell

开源算法 XSS 机器学习识别XSS实践使用深度学习检测XSS使用深度学习检测XSS(续)DNS&DGA检测 使用CNN检测DNS隧道 探秘-基于机器学习的DNS隐蔽隧道检测方法与实现 DNS Tunnel隧道隐蔽

Go语言中的Channel

1. 简介 Channel是Go语言中一种重要的并发原语&#xff0c;它允许goroutine之间安全地交换数据。Channel是一个类型化的队列&#xff0c;它可以存储一个特定类型的值。goroutine可以通过发送和接收操作来向channel中写入和读取数据。 2. Channel的类型 Channel的类型由其元素…

第一次面试复盘

这个秋招到目前为止第一次拿到了面试机会&#xff0c;虽然是小公司&#xff0c;但是人家是有官网的&#xff01;&#xff01;&#xff01;很爱&#xff01;先赶紧复盘一下&#xff0c;因为还有很多笔试没有复盘。 你们的数学建模解决了什么问题&#xff1f;你觉得你们为什么能拿…

CompletableFuture、ListenableFuture高级用列

CompletableFuture 链式 public static void main(String[] args) throws Exception {CompletableFuture<Integer> thenCompose T1().thenCompose(Compress::T2).thenCompose(Compress::T3);Integer result thenCompose.get();System.out.println(result);}// 假设这些…

【Oracle】Oracle编程PLSQL

Oracle编程 一、PL/SQL 1、PL/SQL概述 PL/SQL&#xff08;Procedure Language/SQL&#xff09;是 Oracle 对 sql 语言的过程化扩展&#xff0c;使 SQL 语言具有过程处理能力。 基本语法结构 [declare -- 声明变量 ]begin-- 代码逻辑 [exception-- 异常处理 ]end;2、变量 …

centos7下升级openssh9.4p1及openssl1.1.1v版本

背景&#xff1a;客户服务器扫描出一些漏洞&#xff0c;发现和版本有关&#xff0c;漏洞最高的版本是9.3p2&#xff0c;所以我们安装一个openssh9.4p1版本及openssl1.1.1v版本 虽然我们进行了镜像备份&#xff0c;为了安全先安装telnet以防止升级失败无法通过ssh连接服务器 一…

【会议征稿通知】第二届数字化经济与管理科学国际学术会议(CDEMS 2024)

第二届数字化经济与管理科学国际学术会议&#xff08;CDEMS 2024&#xff09; 2024 2nd International Conference on Digital Economy and Management Science&#xff08;CDEMS 2024&#xff09; 2024年第二届数字经济与管理科学国际会议(CDEMS 2024) 定于2023年4月26-28日…

如何使用统计鸟网站统计分析网站流量来源?

统计鸟官网地址&#xff1a;https://www.tongjiniao.com/ 站长必备&#xff01;网站数据统计&#xff0c;流量监测平台 提供网站数据统计分析、搜索关键词、流量访问来源等服务 深入分析用户点击习惯&#xff0c;为智能化运营网站提供更好的用户体验 目录 一、注册账号信息 二…

基于博弈树的开源五子棋AI教程[3 极大极小搜索]

基于博弈树的开源五子棋AI教程[3 极大极小搜索] 引子极大极小搜索原理alpha-beta剪枝负极大搜索尾记 引子 极大极小搜索是博弈树搜索中最常用的算法&#xff0c;广泛应用于各类零和游戏中&#xff0c;例如象棋&#xff0c;围棋等棋类游戏。算法思想也是合乎人类的思考逻辑的&a…

Flask+ Dependency-injecter+pytest 写测试类

最近在使用这几个在做项目&#xff0c;因为第一次用这个&#xff0c;所以不免有些问题。总结下踩的坑 1.测试类位置 首先测试类约定会放在tests里面&#xff0c;不然有可能发生引入包的问题&#xff0c;会报错某些包找不到。 2. 测试类依赖注入 这里我就用的真实的数据库操作…

Js--数组(三)

1.什么是数组&#xff1f; 数组&#xff1a;(Array)是一种可以按顺序保存数据的数据类型 2.为什么要数组&#xff1f; 思考&#xff1a;如果我想保存一个班里所有同学的姓名怎么办&#xff1f; 场景&#xff1a;如果有多个数据可以用数组保存起来&#xff0c;然后放到一个变量…

MacBook安装Docker

MacBook安装Docker dmg包安装 官方下载dmg安装包: https://docs.docker.com/desktop/mac/install/ 点击安装&#xff0c;然后启动 二进制安装 官方下载二进制包: https://download.docker.com/mac/static/stable/x86_64/ tar -zxvf docker-20.10.0.tgz#将解压出来的docke…

Apppium driver的一些比较重要操作,原生APP和H5 APP(WEBVIEW)

1.reset() //重置app 这时候driver会重置&#xff0c;相当于卸载重装应用。所以本地缓存会失效 driver.reset() 2.start_activity(包名,activity名) //启动app的某一个activity 例如&#xff1a;driver.start_activity("com.wuba.zhuanzhuan","./presentatio…

9个Linux网络命令

这些命令用于监控连接、排除网络故障、路由选择、DNS 查询和接口配置。 1. ping – 向网络主机发送 ICMP ECHO_REQUEST ping 是用于测试网络连接的最流行的网络终端工具。ping 有很多选项&#xff0c;但在大多数情况下&#xff0c;您将使用它来请求域或IP地址&#xff1a; p…

【AI视野·今日CV 计算机视觉论文速览 第285期】Mon, 8 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Mon, 8 Jan 2024 Totally 66 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Denoising Vision Transformers Authors Jiawei Yang, Katie Z Luo, Jiefeng Li, Kilian Q Weinberger, Yonglong Tian, Yue…

【漏洞复现】Apache Tomcat AJP文件包含漏洞(CVE-2020-1938)

Nx01 产品简介 Apache Tomcat 是一个免费的开源 Web 应用服务器&#xff0c;在中小型企业和个人开发用户中有着广泛的应用。 Nx02 漏洞描述 默认情况下&#xff0c;Apache Tomcat会开启AJP连接器&#xff0c;由于AJP服务&#xff08;8009端口&#xff09;存在文件包含缺陷&…