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语言网络编程(并发编程)Sync 1、Sync 1.1.1. sync.WaitGroup 在代码中生硬的使用time.Sleep肯定是不合适的,Go语言中可以使用sync.WaitGroup来实现并发任务的同步。 sync.WaitGroup有以下几个方法: 方法名 功能 (wg * WaitG…...
如何在 Ubuntu 上安装 Nagios?
Nagios 的功能 Nagios 的一些关键功能包括: 主机和服务监控: Nagios 允许您使用提供实时状态数据的插件来监控主机(可以是物理机或虚拟机)以及 HTTP、SSH 和 SMTP 等服务。此功能使您能够全面了解整个基础设施的运行状况和可用性…...
汽车技术发展趋势及我国节能与新能源汽车技术
一、世界汽车技术发展趋势 汽车技术正向着低碳化、信息化、智能化方向发展;“三化”趋势成为世界主要汽车强国、主要车企共同的战略选择。 主要汽车战略及方向 在“三化”趋势下,各汽车强国在汽车节能技术、新能源汽车技术、智能网联汽车技术等方面持续…...
如何实现负载均衡
在如今互联网应用日益火热的背景下,为了保证应用程序的高可用性和高性能,负载均衡变得越来越重要。负载均衡是指将传入的请求分配到多个服务器上,以避免单一服务器的过载,提高系统的可用性和性能。而PHP作为一种广泛使用的服务器端…...
Jetsonnano B01 笔记3:GPIO上拉下拉-输入输出读取
今日继续我的jetsonnano学习之路,今日学习的是GPIO的上拉下拉,输入输出的读取,文章贴出完整操作步骤过程,贴出源码。 目录 Linux常用文件命令: ls(list)列表: man: …...
COMO-ViT论文阅读笔记
Low-Light Image Enhancement with Illumination-Aware Gamma Correction and Complete Image Modelling Network 这是一篇美团、旷视、深先院、华为诺亚方舟实验室、中国电子科技大学 五个单位合作的ICCV2023的暗图增强论文,不过没有开源代码。 文章的贡献点一个是…...
智慧燃气:智慧燃气发展的讨论
关键词:智慧燃气、智能管网、智慧燃气系统、智能燃气、智慧燃气建设、智慧燃气平台 智慧燃气是什么? 智慧燃气是以智能管网建设为基础,利用先进的通信、传感、储能、微电子、数据优化管理和智能控制等技术,实现天然气与其他能源…...
音视频会议需要哪些设备配置
音视频会议需要哪些设备配置?音视频会议需要:视频会议摄像头、麦克风、扬声器、显示设备、网络连接设备、视频会议服务器、视频会议软件等。 1. 视频会议摄像头:用于捕捉与传输视频图像,可以选择高清摄像头,提供更出色…...
性能测试 —— Jmeter事务控制器
事务: 性能测试中,事务指的是从端到端,一个完整的操作过程,比如一次登录、一次 筛选条件查询,一次支付等;技术上讲:事务就是由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)
说明 通过接口,导出表格。 使用SpringBoot框架和easypoi表格解析框架,生成Excel表格,并通过接口下载。 表格示例 依赖 版本 <easypoi.version>4.4.0</easypoi.version>依赖 <!-- easypoi --> <dependency><…...
社群团购对接,【概率思维】可以增加你做项目的成功率!
社群团购对接,【概率思维】可以增加你做项目的成功率! 今天来聊一个关于概率的问题,我们不管去做社群团购项目、做流量,还是做销售,我们都要有概率思维,有了这个思维以后,就可以增加你的成功率…...
不同场景下的JMETER设置
不同场景下的JMETER设置 1.基准测试 验证主要业务在单用户运行下的性能指标,为多用户并发并发和混合场景的性能分析提供基础参考。 基准测试JMETER线程组设置(在1秒内执行5个线程循环一次): 2.并发测试 多用户在同一时间访问某一个模块或则应用的场景&…...
新手请进,Python是什么,Python简介!
Python 是荷兰人 Guido van Rossum (吉多范罗苏姆,中国程序员称其为“龟叔”)在 1990 年初开发的一种解释型编程语言。 图1:Python 的标志(Logo) Python 的诞生是极具戏曲性的,据 Guido 自述记载…...
《Python魔法大冒险》005 魔法挑战:自我介绍机器人
魔法师和小鱼坐在图书馆的一扇窗户旁,窗外的星空闪烁着神秘的光芒。魔法师轻轻地拍了拍小鱼的肩膀。 魔法师: 小鱼,你已经学会了编写简单的魔法程序,现在我要教你如何创造一个有自己思想的机器人,让它能够和我们一样&…...
常见的网络欺诈风险类型有哪些?
身份伪冒,这是非常典型的第三方欺诈,指的是不法分子使用虚假身份证等身份信息、未经他人同意而冒用他人身份获取贷款的骗贷行为。 另外还有帐号垃圾注册,通过大规模的帐号注册,养号养卡,控制帐号骗贷。此外还有中介包装…...
GE IS220PAICH2A 336A4940CSP11 数字量输入模块产品应用领域
GE IS220PAICH2A 336A4940CSP11 是一款数字量输入模块,通常用于工业自动化和控制系统中,用于监测和采集数字输入信号。这种类型的模块可以在各种应用领域中发挥作用,以下是一些可能的应用领域: 工业过程控制: GE IS220…...
element el-table 设置fixed导致行错乱问题
首先看有问题的样式: 解决: // 解决左右 对不齐 的情况 // el-table 左右有列固定时,fixed为left和right时,行未对齐解决办法 // * 产生原因: el-table底部有滚动条,固定列底部没有滚动条 // * 解决办法&…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
