Golang标准库sync的使用
Go语言作为现代编程语言,其并发编程的优势是有目共睹的。在实际编程中,我们常常需要保证多个goroutine之间的同步,这就需要使用到Go语言的sync
标准库。sync
库提供了基本的同步原语,例如互斥锁(Mutex)和等待组(WaitGroup),这些都是协调和控制并发执行的重要工具。
基础应用
1. 使用Mutex实现互斥
在很多情况下,我们需要保证在任意时刻只有一个goroutine能够访问某个数据。这时我们就可以使用Mutex(互斥锁)来实现这个需求。Mutex有两个方法:Lock
和Unlock
。在Lock
和Unlock
之间的代码块,同一时刻只有一个goroutine可以执行,其他尝试执行这部分代码的goroutine会被阻塞直到锁被解开。以下面的例子为例,我们试图在多个goroutine中对一个全局变量完成加法操作:
package mainimport ("fmt""sync"
)var (sum intmu sync.Mutex
)func worker() {for i := 0; i < 10; i++ {mu.Lock()sum = sum + 1mu.Unlock()}
}func main() {var wg sync.WaitGroupfor i := 0; i < 10000; i++ {wg.Add(1)go func() {defer wg.Done()worker()}()}wg.Wait()fmt.Println(sum)
}
2. 使用WaitGroup等待并发操作结束
在另外一种常见的应用场景中,我们需要开启一组goroutine去处理任务,而主goroutine需要等待这些任务完成后才能结束。这可以通过sync.WaitGroup
来实现。WaitGroup有三个方法:Add
增加计数,Done
减少计数,Wait
等待计数归零。
package mainimport ("fmt""sync""time"
)func worker(id int, wg *sync.WaitGroup) {defer wg.Done()fmt.Printf("Worker %d starting\n", id)time.Sleep(time.Second)fmt.Printf("Worker %d done\n", id)
}func main() {var wg sync.WaitGroupfor i := 1; i <= 5; i++ {wg.Add(1)go worker(i, &wg)}wg.Wait()
}
以上的代码中,我们创建了5个worker goroutine,main goroutine 会等待所有的worker都完成工作后才会退出。
进阶应用
以下是一些稍微复杂一些的sync
库的使用例子。
全局单例
使用sync.Once
来保证某个操作只执行一次。这在初始化全局变量或者单例模式中非常有用。
package mainimport ("fmt""sync")var once sync.Oncefunc setup() {fmt.Println("Init function")}func worker(wg *sync.WaitGroup, n int) {once.Do(setup)fmt.Println("Worker", n)wg.Done()}func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go worker(&wg, i)}wg.Wait()}
在以上代码中,我们保证了setup
函数只被执行了一次,即使有10个goroutine都尝试去执行setup
函数。
条件变量
使用sync.Cond
来实现条件变量,这可以使得一个或者多个goroutine等待或者通知事件。
package mainimport ("fmt""sync""time")// Button 定义一个按钮结构体type Button struct {Clicked *sync.Cond}// 模拟一个用户界面func simulate(button *Button) {time.Sleep(time.Second)// 用户点击buttonbutton.Clicked.Broadcast()}func main() {// 初始化Buttonbutton := Button{Clicked: sync.NewCond(&sync.Mutex{})}// 显示信息的goroutinefor i := 0; i < 10; i++ {go func(i int) {// 等待button被点击button.Clicked.L.Lock()defer button.Clicked.L.Unlock()button.Clicked.Wait()// button被点击,显示一条信息fmt.Println("button clicked,", i)}(i)}// 模拟用户点击buttongo simulate(&button)time.Sleep(2 * time.Second)}
处理并发是使用Go语言开发中非常重要的一部分,理解和掌握sync
标准库中的同步原语对于你写出高效可靠的并发程序是非常重要的。
希望这篇文章能够帮助你更好的理解如何在Go语言中进行并发编程,我会非常高兴收到你的反馈~
相关文章:

Golang标准库sync的使用
Go语言作为现代编程语言,其并发编程的优势是有目共睹的。在实际编程中,我们常常需要保证多个goroutine之间的同步,这就需要使用到Go语言的sync标准库。sync库提供了基本的同步原语,例如互斥锁(Mutex)和等待…...

判断两张图片是否完全一致
判断两张图片是否为完全相同的图片 批量判断尺寸 大小 图像展示内容体是否完全一致的图片 import os import hashlib from PIL import Imagedef check_img_repeat(directory):"""批量对图片进行重复性校验是检查一组图像中是否有相同或几乎相同的图像副本。一…...

2024洗地机哪家强?口碑洗地机推荐
现如今,智能家电在人们生活中变得越来越受欢迎,例如智能洗地机的出现,不仅省时省力,还实现了家务清洁的自由。在家庭中,地面清洁一直是一个令人头疼的问题,各种智能家居品牌通过开发各种智能家电产品来解决…...

k8s的资源管理
命令行: kubectl命令行工具优点: 90%以上的场景都可以满足 对资源的增,删,查比较方便,对改不是很友好缺点:命令比较冗长,复杂难记 声明方式:k8s当中的yaml文件实现资源管理----声明式GUI:图形化工具的管理。 查看k8s的…...

docker应用部署(部署MySql,部署Tomcat,部署Nginx,部署Redis)
Docker 应用部署 一、部署MySQL 搜索mysql镜像 docker search mysql拉取mysql镜像 docker pull mysql:5.6创建容器,设置端口映射、目录映射 # 在/root目录下创建mysql目录用于存储mysql数据信息 mkdir ~/mysql cd ~/mysqldocker run -id \ -p 3307:3306 \ --na…...

非常好用的ocr图片文字识别技术,识别图片中的文字
目录 一.配置环境 二.应用 2.1常见图片识别 2.2排版简单的印刷体截图图片识别 2.3竖排文字识别 2.4英文识别 2.5繁体中文识别 2.6单行文字的图片识别 三.参考 一.配置环境 pip3 install cnocr -i https://pypi.tuna.tsinghua.edu.cn/simple pip3 install onnxruntime…...

20231227在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单后摄像头ov13850
20231227在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单后摄像头ov13850 2023/12/27 18:40 1、简略步骤: rootrootrootroot-X99-Turbo:~/3TB$ cat Android11.0.tar.bz2.a* > Android11.0.tar.bz2 rootrootrootroot-X99-Turbo:~/3TB$ tar jxvf Androi…...

Unity中Shader裁剪空间推导(透视相机到裁剪空间的转化矩阵)
文章目录 前言一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化1、观察空间(右手坐标系、透视相机)2、裁剪空间(左手坐标系、且转化为了齐次坐标)3、屏幕空间(把裁剪坐标归一化设置)4、从观察空…...

企业签名分发对移动应用开发者有什么影响
企业签名分发是移动应用开发者在应用程序发布前测试、内部分发和特定的受众群体分发等方面比较常用的一种工具。那对于应用商城分发有啥区别,下面简单的探讨一下。 独立分发能力 通过企业签名分发开发者可以自己决定应用程序的发布时间和方式,不用受应用…...

3D游戏角色建模纹理贴图处理
在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 在本文中,我们将介绍 3D 纹理的基础知识,并讨…...

【C++ 单例模式】
正确的析构 静态实例和回收类 SingletonMode.cpp #include <iostream> #include <pthread.h>class Singleton {private:Singleton(){std::cout << "构造" << std::endl;};~Singleton(){std::cout << "析构" << std::…...

React16源码: ConcurrentMode的使用及源码实现
ConcurrentMode 1 ) 概述 ConcurrentMode 是 React 16 出来的一个最令人振奋的功能在2018年年初是 Async Mode,在发布了16.6之后,名字进行了更新然后改成了 ConcurrentMode,中间的API有一个过渡的版本,后续会提到它其实是 React…...

SQL性能优化-索引
1.性能下降sql慢执行时间长等待时间长常见原因 1)索引失效 索引分为单索、复合索引。 四种创建索引方式 create index index_name on user (name); create index index_name_2 on user(id,name,email); 2)查询语句较烂 3)关联查询太多join&a…...

Ubuntu本地快速搭建web小游戏网站,公网用户远程访问
🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…...

easyrecovery 2024最新免费密钥分享 实用数据恢复软件分享
在日常使用电脑时,我们经常会遇到误删文件的情况,若文件还未被彻底删除,我们还可以通过电脑中的回收站将其恢复,但若是回收站都被清空的话,想要恢复文件就变得比较困难了,而EasyRecovery可以很好的帮助我们…...

2.4信道复用技术
目录 2.4信道复用技术2.4.1频分复用、时分复用和统计时分复用频分复用FDM(Frequency Division Multiplexing)时分复用TDM(Time Division Multiplexing)统计时分复用STDM(Statistic TDM) 2.4.2波分复用2.4.3…...

JVM篇:JVM的简介
JVM简介 JVM全称为Java Virtual Machine,翻译过来就是java虚拟机,Java程序(Java二进制字节码)的运行环境 JVM的优点: Java最大的一个优点是,一次编写,到处运行。之所以能够实现这个功能就是依…...

uniapp 输入手机号并且正则校验
1.<input input“onInput” :value“phoneNum” type“number” maxlength“11”/> 3. method里面写 onInput(e){ this.phoneNum e.detail.value }, 4.调用接口时候校验正则 if (!/^1[3456789]\d{9}$/.test(this.phoneNum)) {uni.showToast({title: 请输入正确的手机号…...

经典目标检测YOLO系列(一)复现YOLOV1(3)正样本的匹配及损失函数的实现
经典目标检测YOLO系列(一)复现YOLOV1(3)正样本的匹配及损失函数的实现 之前,我们依据《YOLO目标检测》(ISBN:9787115627094)一书,提出了新的YOLOV1架构,并解决前向推理过程中的两个问题,继续按照此书进行YOLOV1的复现。 经典目标…...

kbdnecat.DLL文件缺失,软件或游戏无法启动运营,快速修复方法
“kbdnecat.DLL文件是什么?为什么一起动游戏或软件,Windows就报错“kbdnecat.DLL文件缺失,软件无法启动””,应该怎么修复呢? 首先,先来了解“kbdnecat.DLL文件”是什么? kbdnecat.DLL是一个动…...

Dockerfile与DockerCompose
Docker的Image结构是怎样的? 镜像是将应用程序 及其需要的 系统函数库、环境、配置、依赖 打包而成。 镜像结构 入口( Entrypoint ) 镜像运行入口,一般是程序启动的脚本和参数 层( Layer ) 在BaseImage基…...

【CFP-专栏2】计算机类SCI优质期刊汇总(含IEEE/Top)
一、计算机区块链类SCI-IEEE 【期刊概况】IF:4.0-5.0, JCR2区,中科院2区; 【大类学科】计算机科学; 【检索情况】SCI在检; 【录用周期】3-5个月左右录用; 【截稿时间】12.31截稿; 【接收领域】区块链…...

Stable Diffusion 本地部署详细教程
目录 一、前言二、系统和硬件要求三、安装前说明四、安装步骤5、升级pip(这是管理python环境软件工具),并把资源库换成国内地址为清华镜像。一、前言 虽然MJ和SD都可以生成图像,但是为什么我们要考虑使用本地SD部署呢?原因其实很简单:首先,本地部署的使用成本更低,且更加…...

【超图】SuperMap iClient3D for WebGL/WebGPU —— 坐标系位置 —— Cartesian2
作者:taco 说到关于地理必然逃不开位置的关系。借用百度百科的内容来说地理学(geography),是研究地球表层空间地理要素或者地理综合体空间分布规律、时间演变过程和区域特征的一门学科。所以位置&坐标系必然逃不掉了。那么在S…...

【Matlab】LSTM长短期记忆神经网络时序预测算法(附代码)
资源下载: https://download.csdn.net/download/vvoennvv/88688439 一,概述 LSTM(Long Short-Term Memory)是一种常用的循环神经网络(Recurrent Neural Network,RNN)结构,由于其对于…...

2.2 设计FMEA步骤二:结构分析
2.2.1 目的 设计结构分析的目的是将设计识别和分解为系统、子系统、组件和零件,以便进行技术风险分析。其主要目标包括: 可视化分析范围结构化表示:方块图、边界图、数字模型、实体零件识别设计接口、交互作用和间隙促进顾客和供应商工程团队之间的协作(接口责任)为功能分…...

红队攻防实战之DC2
吾愿效法古圣先贤,使成千上万的巧儿都能在21世纪的中华盛世里,丰衣足食,怡然自得 0x01 信息收集: 1.1 端口探测 使用nmap工具 可以发现开放了80端口,网页服务器但是可以看出做了域名解析,所以需要在本地完成本地域名…...

【28】Kotlin语法进阶——使用协程编写高效的并发程序
提示:此文章仅作为本人记录日常学习使用,若有存在错误或者不严谨得地方欢迎指正。 文章目录 一、Kotlin中的协程1.1 协程的基本用法1.1.1协程与协程作用域1.1.2 使用launch函数创建子协程1.1.3 通过suspend关键声明挂起函数1.1.4 coroutineScope函数 1.2…...

【大数据面试知识点】Spark的DAGScheduler
Spark数据本地化是在哪个阶段计算首选位置的? 先看一下DAGScheduler的注释,可以看到DAGScheduler除了Stage和Task的划分外,还做了缓存的跟踪和首选运行位置的计算。 DAGScheduler注释: The high-level scheduling layer that i…...

Pycharm引用其他文件夹的py
Pycharm引用其他文件夹的py 方式1:包名设置为Sources ROOT 起包名的时候,需要在该文件夹上:右键 --> Mark Directory as --> Sources ROOT 标记目录为源码目录,就可以了。 再引用就可以了 import common from aoeweb impo…...