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

GO语言网络编程(并发编程)Sync

GO语言网络编程(并发编程)Sync

1、Sync

1.1.1. sync.WaitGroup

在代码中生硬的使用time.Sleep肯定是不合适的,Go语言中可以使用sync.WaitGroup来实现并发任务的同步。 sync.WaitGroup有以下几个方法:

方法名 功能
(wg * WaitGroup) Add(delta int) 计数器+delta
(wg *WaitGroup) Done() 计数器-1
(wg *WaitGroup) Wait() 阻塞直到计数器变为0
sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。

我们利用sync.WaitGroup将上面的代码优化一下:

var wg sync.WaitGroupfunc hello() {defer wg.Done()fmt.Println("Hello Goroutine!")
}
func main() {wg.Add(1)go hello() // 启动另外一个goroutine去执行hello函数fmt.Println("main goroutine done!")wg.Wait()
}

需要注意sync.WaitGroup是一个结构体,传递的时候要传递指针。

1.1.2 sync.Once

说在前面的话:这是一个进阶知识点。

在编程的很多场景下我们需要确保某些操作在高并发的场景下只执行一次,例如只加载一次配置文件、只关闭一次通道等。

Go语言中的sync包中提供了一个针对只执行一次场景的解决方案–sync.Once。

sync.Once只有一个Do方法,其签名如下:

func (o *Once) Do(f func()) {}

注意:如果要执行的函数f需要传递参数就需要搭配闭包来使用。

加载配置文件示例

延迟一个开销很大的初始化操作到真正用到它的时候再执行是一个很好的实践。因为预先初始化一个变量(比如在init函数中完成初始化)会增加程序的启动耗时,而且有可能实际执行过程中这个变量没有用上,那么这个初始化操作就不是必须要做的。我们来看一个例子:

var icons map[string]image.Imagefunc loadIcons() {icons = map[string]image.Image{"left":  loadIcon("left.png"),"up":    loadIcon("up.png"),"right": loadIcon("right.png"),"down":  loadIcon("down.png"),}
}// Icon 被多个goroutine调用时不是并发安全的
func Icon(name string) image.Image {if icons == nil {loadIcons()}return icons[name]
}

多个goroutine并发调用Icon函数时不是并发安全的,现代的编译器和CPU可能会在保证每个goroutine都满足串行一致的基础上自由地重排访问内存的顺序。loadIcons函数可能会被重排为以下结果:

func loadIcons() {icons = make(map[string]image.Image)icons["left"] = loadIcon("left.png")icons["up"] = loadIcon("up.png")icons["right"] = loadIcon("right.png")icons["down"] = loadIcon("down.png")
}

在这种情况下就会出现即使判断了icons不是nil也不意味着变量初始化完成了。考虑到这种情况,我们能想到的办法就是添加互斥锁,保证初始化icons的时候不会被其他的goroutine操作,但是这样做又会引发性能问题。

使用sync.Once改造的示例代码如下:

var icons map[string]image.Imagevar loadIconsOnce sync.Oncefunc loadIcons() {icons = map[string]image.Image{"left":  loadIcon("left.png"),"up":    loadIcon("up.png"),"right": loadIcon("right.png"),"down":  loadIcon("down.png"),}
}// Icon 是并发安全的
func Icon(name string) image.Image {loadIconsOnce.Do(loadIcons)return icons[name]
}

sync.Once其实内部包含一个互斥锁和一个布尔值,互斥锁保证布尔值和数据的安全,而布尔值用来记录初始化是否完成。这样设计就能保证初始化操作的时候是并发安全的并且初始化操作也不会被执行多次。

1.1.3 sync.Map

Go语言中内置的map不是并发安全的。请看下面的示例:

var m = make(map[string]int)func get(key string) int {return m[key]
}func set(key string, value int) {m[key] = value
}func main() {wg := sync.WaitGroup{}for i := 0; i < 20; i++ {wg.Add(1)go func(n int) {key := strconv.Itoa(n)set(key, n)fmt.Printf("k=:%v,v:=%v\n", key, get(key))wg.Done()}(i)}wg.Wait()
}

上面的代码开启少量几个goroutine的时候可能没什么问题,当并发多了之后执行上面的代码就会报fatal error: concurrent map writes错误。

像这种场景下就需要为map加锁来保证并发的安全性了,Go语言的sync包中提供了一个开箱即用的并发安全版map–sync.Map。开箱即用表示不用像内置的map一样使用make函数初始化就能直接使用。同时sync.Map内置了诸如Store、Load、LoadOrStore、Delete、Range等操作方法。

var m = sync.Map{}func main() {wg := sync.WaitGroup{}for i := 0; i < 20; i++ {wg.Add(1)go func(n int) {key := strconv.Itoa(n)m.Store(key, n)value, _ := m.Load(key)fmt.Printf("k=:%v,v:=%v\n", key, value)wg.Done()}(i)}wg.Wait()
}

相关文章:

GO语言网络编程(并发编程)Sync

GO语言网络编程&#xff08;并发编程&#xff09;Sync 1、Sync 1.1.1. sync.WaitGroup 在代码中生硬的使用time.Sleep肯定是不合适的&#xff0c;Go语言中可以使用sync.WaitGroup来实现并发任务的同步。 sync.WaitGroup有以下几个方法&#xff1a; 方法名 功能 (wg * WaitG…...

如何在 Ubuntu 上安装 Nagios?

Nagios 的功能 Nagios 的一些关键功能包括&#xff1a; 主机和服务监控&#xff1a; Nagios 允许您使用提供实时状态数据的插件来监控主机&#xff08;可以是物理机或虚拟机&#xff09;以及 HTTP、SSH 和 SMTP 等服务。此功能使您能够全面了解整个基础设施的运行状况和可用性…...

汽车技术发展趋势及我国节能与新能源汽车技术

一、世界汽车技术发展趋势 汽车技术正向着低碳化、信息化、智能化方向发展&#xff1b;“三化”趋势成为世界主要汽车强国、主要车企共同的战略选择。 主要汽车战略及方向 在“三化”趋势下&#xff0c;各汽车强国在汽车节能技术、新能源汽车技术、智能网联汽车技术等方面持续…...

如何实现负载均衡

在如今互联网应用日益火热的背景下&#xff0c;为了保证应用程序的高可用性和高性能&#xff0c;负载均衡变得越来越重要。负载均衡是指将传入的请求分配到多个服务器上&#xff0c;以避免单一服务器的过载&#xff0c;提高系统的可用性和性能。而PHP作为一种广泛使用的服务器端…...

Jetsonnano B01 笔记3:GPIO上拉下拉-输入输出读取

今日继续我的jetsonnano学习之路&#xff0c;今日学习的是GPIO的上拉下拉&#xff0c;输入输出的读取&#xff0c;文章贴出完整操作步骤过程&#xff0c;贴出源码。 目录 Linux常用文件命令&#xff1a; ls&#xff08;list&#xff09;列表&#xff1a; man&#xff1a; …...

COMO-ViT论文阅读笔记

Low-Light Image Enhancement with Illumination-Aware Gamma Correction and Complete Image Modelling Network 这是一篇美团、旷视、深先院、华为诺亚方舟实验室、中国电子科技大学 五个单位合作的ICCV2023的暗图增强论文&#xff0c;不过没有开源代码。 文章的贡献点一个是…...

智慧燃气:智慧燃气发展的讨论

关键词&#xff1a;智慧燃气、智能管网、智慧燃气系统、智能燃气、智慧燃气建设、智慧燃气平台 智慧燃气是什么&#xff1f; 智慧燃气是以智能管网建设为基础&#xff0c;利用先进的通信、传感、储能、微电子、数据优化管理和智能控制等技术&#xff0c;实现天然气与其他能源…...

音视频会议需要哪些设备配置

音视频会议需要哪些设备配置&#xff1f;音视频会议需要&#xff1a;视频会议摄像头、麦克风、扬声器、显示设备、网络连接设备、视频会议服务器、视频会议软件等。 1. 视频会议摄像头&#xff1a;用于捕捉与传输视频图像&#xff0c;可以选择高清摄像头&#xff0c;提供更出色…...

性能测试 —— Jmeter事务控制器

事务&#xff1a; 性能测试中&#xff0c;事务指的是从端到端&#xff0c;一个完整的操作过程&#xff0c;比如一次登录、一次 筛选条件查询&#xff0c;一次支付等&#xff1b;技术上讲&#xff1a;事务就是由1个或多个请求组成的 事务控制器 事务控制器类似简单控制器&…...

【Tomcat7部署Springboot版本不兼容问题】

Tomcat7部署Springboot版本不兼容 报错网上解决方案tomcat7可以部署springboot哪些版本分析原因解决方法 报错 SEVERE: Unable to deploy collapsed ear in war StandardEngine[Catalina].StandardHost[localhost].StandardContext[/demo] org.apache.openejb.OpenEJBException…...

RabbitMQ消息中间件

RabbitMQ消息中间件 RabbitMQ简介windows下安装RabbitMQRabbitMQ基本概念RabbitMQ简单模式RabbitMQ工作队列模式RabbitMQ发布订阅模式RabbitMQ路由模式RabbitMQ主题模式RabbitMQ RPC模式RabbitMQ发布确认模式...

UNIAPP之js/nvue混淆探索

因项目需要对UNIAPP的js混淆做了一些调研 混淆教程: https://uniapp.dcloud.net.cn/tutorial/app-sec-confusion.html 按照教程配置进行打包正式包进行混淆 下载正式包将 .ipa改为.zip 解压获取到HBuilder.app 右键显示包内容 获取到混淆的key 不同时间进行打包混淆同一文…...

Excel文件生成与下载(SpringBoot项目)(easypoi)

说明 通过接口&#xff0c;导出表格。 使用SpringBoot框架和easypoi表格解析框架&#xff0c;生成Excel表格&#xff0c;并通过接口下载。 表格示例 依赖 版本 <easypoi.version>4.4.0</easypoi.version>依赖 <!-- easypoi --> <dependency><…...

社群团购对接,【概率思维】可以增加你做项目的成功率!

社群团购对接&#xff0c;【概率思维】可以增加你做项目的成功率&#xff01; 今天来聊一个关于概率的问题&#xff0c;我们不管去做社群团购项目、做流量&#xff0c;还是做销售&#xff0c;我们都要有概率思维&#xff0c;有了这个思维以后&#xff0c;就可以增加你的成功率…...

不同场景下的JMETER设置

不同场景下的JMETER设置 1.基准测试 验证主要业务在单用户运行下的性能指标&#xff0c;为多用户并发并发和混合场景的性能分析提供基础参考。 基准测试JMETER线程组设置(在1秒内执行5个线程循环一次)&#xff1a; 2.并发测试 多用户在同一时间访问某一个模块或则应用的场景&…...

新手请进,Python是什么,Python简介!

Python 是荷兰人 Guido van Rossum &#xff08;吉多范罗苏姆&#xff0c;中国程序员称其为“龟叔”&#xff09;在 1990 年初开发的一种解释型编程语言。 图1&#xff1a;Python 的标志&#xff08;Logo&#xff09; Python 的诞生是极具戏曲性的&#xff0c;据 Guido 自述记载…...

《Python魔法大冒险》005 魔法挑战:自我介绍机器人

魔法师和小鱼坐在图书馆的一扇窗户旁&#xff0c;窗外的星空闪烁着神秘的光芒。魔法师轻轻地拍了拍小鱼的肩膀。 魔法师&#xff1a; 小鱼&#xff0c;你已经学会了编写简单的魔法程序&#xff0c;现在我要教你如何创造一个有自己思想的机器人&#xff0c;让它能够和我们一样&…...

常见的网络欺诈风险类型有哪些?

身份伪冒&#xff0c;这是非常典型的第三方欺诈&#xff0c;指的是不法分子使用虚假身份证等身份信息、未经他人同意而冒用他人身份获取贷款的骗贷行为。 另外还有帐号垃圾注册&#xff0c;通过大规模的帐号注册&#xff0c;养号养卡&#xff0c;控制帐号骗贷。此外还有中介包装…...

GE IS220PAICH2A 336A4940CSP11 数字量输入模块产品应用领域

GE IS220PAICH2A 336A4940CSP11 是一款数字量输入模块&#xff0c;通常用于工业自动化和控制系统中&#xff0c;用于监测和采集数字输入信号。这种类型的模块可以在各种应用领域中发挥作用&#xff0c;以下是一些可能的应用领域&#xff1a; 工业过程控制&#xff1a; GE IS220…...

element el-table 设置fixed导致行错乱问题

首先看有问题的样式&#xff1a; 解决&#xff1a; // 解决左右 对不齐 的情况 // el-table 左右有列固定时&#xff0c;fixed为left和right时&#xff0c;行未对齐解决办法 // * 产生原因&#xff1a; el-table底部有滚动条&#xff0c;固定列底部没有滚动条 // * 解决办法&…...

英文论文降AI用什么工具?Turnitin检测实测推荐

英文论文降AI用什么工具&#xff1f;Turnitin检测实测推荐 英文论文降AI用什么工具&#xff1f;Turnitin检测实测推荐 中文论文降AI工具一大把&#xff0c;但英文论文呢&#xff1f; 特别是投SCI或者在海外读硕博的同学&#xff0c;Turnitin已经全面集成了AI检测功能。不少人投…...

别再只用pretrained=True了!timm库加载模型权重的5种实战姿势(附避坑清单)

解锁timm库模型权重加载的5种高阶玩法&#xff1a;从精准控制到性能优化 在深度学习项目实践中&#xff0c;模型权重的加载远不止pretrainedTrue这么简单。当你需要处理自定义权重、进行模型微调或优化加载性能时&#xff0c;timm库提供了丰富的底层控制接口。本文将深入剖析五…...

人工智能应用- 预测新冠病毒传染性:07. 预测不同类型病毒的传播能力

研究者利用 M-H 模型对各个病毒变种的传播能力进行了研究&#xff0c;结果如图所示&#xff1a;图: AI 模型预测的病毒传播力。横轴为变种出现时间&#xff0c;纵轴为预测传播能力&#xff0c;表示为相对基本再生数&#xff08;R/RA&#xff0c;其中 RA 是武汉变种的基本再生数…...

Python枚举的高级玩法:从状态机到策略模式的优雅实现

Python枚举的高级玩法&#xff1a;从状态机到策略模式的优雅实现 在Python开发中&#xff0c;枚举&#xff08;Enum&#xff09;常被简单地用作常量集合&#xff0c;但它的潜力远不止于此。对于熟悉设计模式的中高级开发者来说&#xff0c;枚举可以成为简化复杂模式实现的利器。…...

自动泊车路径规划优化算法

自动泊车车位检测及改进混合a星算法的路径规划&#xff0c;其中包括环境地图建模&#xff0c;路径规划及优化程序。 。 。 平行垂直斜向都有&#xff0c; 自动泊车的技术栈里有两个硬骨头&#xff1a;怎么在混乱的停车场精准找到车位&#xff0c;以及如何生成一条让车子能倒进…...

基于Matlab的FFT滤波:谐波分析、频段清除与数据提取

基于matlab的FFT滤波&#xff0c;可以实现对simulink模型中示波器的波形数据或者外部mat数据、csv数据进行谐波分析(FFT)和自定义频段清除&#xff0c;对已有数据特定频段的数据进行提取也可以。 优点是滤波前后波形无相位滞后&#xff0c;幅值衰减可补偿&#xff0c;不足之处在…...

Debian 13 KDE桌面美化全攻略:从Nordic主题到Papirus图标一步到位

Debian 13 KDE桌面美学革命&#xff1a;打造极简高效的开发者工作环境 在开源世界的浩瀚星空中&#xff0c;KDE Plasma桌面环境以其高度可定制性和现代感的设计语言&#xff0c;成为众多开发者的首选。Debian 13作为Linux发行版中的常青树&#xff0c;其稳定性与KDE的灵活性相结…...

人工智能如何改变 Anthropic 的工作方式15

如果有一天&#xff0c;你走进公司&#xff0c;发现写代码、查 bug、跑实验的大部分体力活&#xff0c;都已经由一位看不见的 AI 搭档在后台悄悄完成了——而你更多是在提问题、定方向、做决策&#xff0c;而不是一行行敲代码&#xff0c;这会是什么感觉&#xff1f;是兴奋&…...

OpenCV去畸变实战:手把手教你用undistortPoints搞定鱼眼镜头图像矫正(附Python代码)

OpenCV鱼眼镜头去畸变实战&#xff1a;从标定到undistortPoints的完整指南 当你第一次用鱼眼镜头拍摄图像时&#xff0c;可能会惊讶地发现直线变成了曲线——这就是镜头畸变在作祟。对于计算机视觉开发者来说&#xff0c;这种畸变会严重影响特征点匹配、三维重建和目标跟踪的精…...

Ubuntu24.04下Librenms安装全攻略:从依赖包到网页配置一步到位

Ubuntu 24.04 下 LibreNMS 专业部署指南&#xff1a;从零构建企业级网络监控系统 对于现代IT运维团队来说&#xff0c;一套可靠的网络监控系统就像航海中的雷达&#xff0c;能提前发现潜在风险。LibreNMS作为开源的网络监控解决方案&#xff0c;以其全面的设备支持和灵活的告警…...