Go 使用sync.Mutex或sync.RWMutex进行并发安全访问

一、使用sync.Mutex或sync.RWMutex进行并发安全访问

当多个协程并发访问共享数据时,需要确保数据访问的安全性。sync.Mutex和sync.RWMutex提供了互斥锁和读写锁,用于在访问共享资源之前进行锁定,以避免数据竞争。

sync.Mutex

package mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupvar mutex sync.Mutexvar data intvar num = 20000wg.Add(2)go func() {defer wg.Done()for i := 0; i < num; i++ {// 写操作,使用互斥锁保护数据mutex.Lock() //上了锁是还可以读的data++mutex.Unlock()}}()go func() {defer wg.Done()for i := 0; i < num; i++ {// 写操作,使用互斥锁保护数据mutex.Lock() //上了锁是还可以读的data++mutex.Unlock()}}()wg.Wait()fmt.Println(data)fmt.Println("在并发的情况下,当num数大到一定程度,如果不加锁就会出现最终运算结果不正确的情况")
}

ync.RWMutex

sync.RWMutex是Go语言提供的一个基础同步原语,它是Reader/Writer Mutual Exclusion Lock的缩写,通常被称为"读写锁"。读写锁允许多个读锁同时拥有者,但在任何时间点只允许一个写锁拥有者,或者没有锁拥有者。

sync.RWMutex提供了以下方法:

type RWMutex
// 获取写锁,有读锁或者写锁被其他goroutine使用则阻塞等待
func (rw *RWMutex) Lock()
// 尝试获取写锁,获取到则返回true,没有获取到则为false
func (rw *RWMutex) TryLock() bool
// 释放写锁
func (rw *RWMutex) Unlock()
// 获取读锁,
func (rw *RWMutex) RLock()
// 尝试获取读锁,获取到则返回true,没有获取到则为false
func (rw *RWMutex) TryRLock() bool
// 释放读锁
func (rw *RWMutex) RUnlock()// 返回Locker
func (rw *RWMutex) RLocker() Locker

注意:
使用RWMutex的时候,一旦调用了Lock方法,就不能再把该锁复制到其他地方使用,否则可能会出现各种问题。这是由于锁的状态(被哪个协程持有,是否已经被锁定等)是存储在RWMutex的结构体中,如果复制了RWMutex,那么复制后的RWMutex就会有一个全新的状态,锁的行为就会变得不可预测。
RWMutex和Mutex一样,一旦有了Lock调用就不能到处copy了,否则出现各种问题。

sync.RWMutex 包含两个主要的方法:

  1. RLock():用于读锁,多个goroutine可以同时调用此方法获取读锁。

  2. RUnlock():用于释放读锁。

  3. Lock():用于写锁,当有goroutine调用此方法时,其他goroutine的读锁和写锁请求都会被阻塞,直到写锁被释放。

  4. Unlock():用于释放写锁。

package mainimport ("fmt""strconv""sync""time"
)func main() {fmt.Println("通过使用 sync.RWMutex,我们可以确保即使在高并发的情况下,对值的读写也是安全的")fmt.Println("Lock与RLock配合,使用使得写入的时候阻塞不给读取,等写完了再读")var (mu    sync.RWMutex // 创建一个RWMutex实例count int)var wg sync.WaitGroupwg.Add(3)go func() {defer wg.Done()// 启动一些goroutine来增加count的值for j := 0; j < 100; j++ {mu.Lock() // 获取写锁fmt.Println("获取写锁Lock--其他goroutine的读锁和写锁请求都会被阻塞,直到写锁被释放")time.Sleep(3000 * time.Millisecond)count++fmt.Println()fmt.Println("---------------写锁被释放----------")mu.Unlock() // 释放写锁}}()time.Sleep(time.Millisecond)go func() {defer wg.Done()// 启动一些goroutine来读取count的值for j := 0; j < 100; j++ {mu.RLock() // 获取读锁fmt.Println("获取读锁RLock--多个goroutine可以同时调用此方法获取读锁count=" + strconv.Itoa(count))mu.RUnlock() // 释放读锁}}()go func() {defer wg.Done()// 启动一些goroutine来读取count的值for j := 0; j < 100; j++ {mu.RLock() // 获取读锁fmt.Println("获取读锁RLock--多个goroutine可以同时调用此方法获取读锁count=" + strconv.Itoa(count))mu.RUnlock() // 释放读锁}}()wg.Wait()fmt.Println("Final count:", count)
}

更详细可参考:逐步学习Go-sync.RWMutex(读写锁)-深入理解与实战-CSDN博客

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

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

相关文章

谈【AI在创造还是在毁掉音乐】

AI在创造音乐方面确实具有极大的潜力&#xff0c;但从长远来看&#xff0c;它更有可能毁掉音乐。 首先&#xff0c;AI生成的音乐缺乏情感和灵感。音乐是一种表达情感和思想的艺术形式&#xff0c;而AI只是通过算法分析和模仿已有的音乐来生成新的作品。它缺乏创造力和独特性&a…

【验证码识别】Yolov8实战某验3空间推理点选验证码,目标检测,语义分割,颜色分类。

【验证码识别】Yolov8实战某验3空间推理点选验证码&#xff0c;目标检测&#xff0c;语义分割&#xff0c;颜色分类。 文章目录 【验证码识别】Yolov8实战某验3空间推理点选验证码&#xff0c;目标检测&#xff0c;语义分割&#xff0c;颜色分类。声明1.空间推理验证码&#xf…

2024年全国青少信息素养大赛python编程复赛集训第四天编程题分享

整理资料不容易,感谢各位大佬给个点赞和分享吧,谢谢 大家如果不想阅读前边的比赛内容介绍,可以直接跳过:拉到底部看集训题目 (一)比赛内容: 【小学组】 1.了解输入与输出的概念,掌握使用基本输入输出和简单运算 为主的标准函数; 2.掌握注释的方法; 3.掌握基本数…

Studying-代码随想录训练营day17| 654.最大二叉树、617合并二叉树、700.二叉搜索树中的搜索、98.验证二叉树搜索树

第十七天&#xff0c;二叉树part05&#xff0c;进一步学习二叉树&#x1f4aa; 654.最大二叉树 文档讲解&#xff1a;代码随想录最大二叉树 视频讲解&#xff1a;手撕最大二叉树 题目&#xff1a; 学习&#xff1a;本题与利用中序和后序序列构造二叉树有相同之处。依据题目要求…

第五篇:构建与维护私有Docker Registry: 企业级实践指南

构建与维护私有Docker Registry: 企业级实践指南 1. 引言&#xff1a;解析私有Docker仓库的必要性 1.1 Docker Registry简介与私有化的好处 Docker Registry是一个用于存储和分发Docker镜像的系统。在Docker生态系统中&#xff0c;Registry扮演着至关重要的角色&#xff0c;为…

洛谷:P5714 【深基3.例7】肥胖问题

1. 题目链接 https://www.luogu.com.cn/problem/P5714 P5714 【深基3.例7】肥胖问题 2. 题目描述 题目描述&#xff1a;BMI计算:m / (h * h)&#xff0c;m是体重(kg)&#xff0c;h是身高(m) 小于18.5&#xff1a;体重国轻&#xff0c;Underweight 小于等于18.5且小于24&#…

骨传导耳机值不值得入手?五款运动好物骨传导耳机推荐!

开放式耳机在如今社会中已经迅速成为大家购买耳机的新趋势&#xff0c;开放式蓝牙耳机作为骨传导耳机&#xff0c;深受喜欢听歌和热爱运动的人群欢迎。当大家谈到佩戴的稳固性时&#xff0c;后挂式骨传导耳机都会收到一致好评。对于热爱运动的人士而言&#xff0c;高品质的骨传…

A800显卡驱动安装(使用deb安装)

重新安装显卡驱动&#xff0c;查阅了资料将过程记录如下&#xff1a; 1.下载deb安装包 打开nvidia官网查找对应的驱动版本&#xff0c;A800所在的选项卡位置如图&#xff1a; 点击查找后下载得到的是nvidia-driver-local-repo-ubuntu2004-550.90.07_1.0-1_amd64.deb安装包 2.…

从零到一学FFmpeg:avcodec_open2 函数详析与实战

文章目录 前言一、函数原型二、功能描述三、使用实例 前言 avcodec_open2是FFmpeg库中的一个关键函数&#xff0c;用于根据给定的AVCodecContext和AVCodec实例初始化编解码器&#xff0c;使其准备好进行编解码操作。 这个函数是编解码流程中配置编解码器上下文后的重要一步&am…

不同点云聚类提取方法(模型、距离、密度)

目录 一、简介 二、点云聚类方法 1.基于距离的聚类方法 2.基于密度的聚类方法 3.基于模型的聚类方法 三、不同实现方式 1.平面模型 2.欧氏距离聚类 四、实现结果 一、简介 点云聚类方法是一种将点云数据进行分组的技术,在三维扫描、计算机视觉和机器人领域中,点云数据…

UDS服务——RequestDownload(0x34)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍RequestDownload(0x34)—— 请求下载,用于给ECU下载数据的,最常见的应用就是在bootloader中,程序下载工具会发起请求下载,以完成ECU程序的升级。通过阅读本文,希望能对你有所帮助。 文章目录 诊断协议那些事儿…

【康复学习--LeetCode每日一题】2288. 价格减免

题目&#xff1a; 句子 是由若干个单词组成的字符串&#xff0c;单词之间用单个空格分隔&#xff0c;其中每个单词可以包含数字、小写字母、和美元符号 ‘$’ 。如果单词的形式为美元符号后跟着一个非负实数&#xff0c;那么这个单词就表示一个 价格 。 例如 “$100”、“$23”…

linux如何部署前端项目和安装nginx

要在Linux上部署前端项目并安装Nginx&#xff0c;你可以按照以下步骤操作&#xff1a; 安装Nginx: sudo apt update sudo apt install nginx 启动Nginx服务: sudo systemctl start nginx 确保Nginx服务开机自启: sudo systemctl enable nginx 部署前端项目&#xff0c;假设前…

萨科微slkor宋仕强论道华强北假货之六

萨科微slkor宋仕强论道华强北假货之六&#xff0c;华强北的假货这么多&#xff0c;搞得客户害怕、同行焦虑&#xff0c;话说“在华强北没有被坑过的&#xff0c;就不是华强北人”。我们金航标Kinghelm&#xff08;www.kinghelm.com.cn&#xff09;公司以前有一个贸易部&#xf…

45、基于深度学习的螃蟹性别分类(matlab)

1、基于深度学习的螃蟹性别分类原理及流程 基于深度学习的螃蟹性别分类原理是利用深度学习模型对螃蟹的图像进行训练和识别&#xff0c;从而实现对螃蟹性别的自动分类。整个流程可以分为数据准备、模型构建、模型训练和性别分类四个步骤。 数据准备&#xff1a; 首先需要收集包…

构造方法可以调用本类中重载的构造方法和它的父类的构造方法

1.调用本类中重载的构造方法&#xff1a;构造方法可以通过this()来调用本类中其他重载的构造方法。但是&#xff0c;这个调用必须位于构造方法的第一行&#xff0c;也就是说&#xff0c;它是构造方法中的第一个语句。这是因为构造方法需要先完成一些初始化工作&#xff0c;然后…

【报错解决】引入@ComponentScan注解注册bean容器后,导致的接口404问题

引入ComponentScan注解注册bean容器后&#xff0c;导致的接口404问题 背景 由于微服务开发中&#xff0c;经常需要在公共模块在引入一些公共模块&#xff0c;供其他服务使用&#xff0c;但是其他服务需要在启动类中配置ComponentScan注解扫描这个公共模块下注册的 bean&#…

一篇文章带你学会“二分算法”

二分算法&#xff08;也称为二分法或折半查找&#xff09;是一种在有序数组中查找特定元素的搜索算法。其基本原理是通过不断缩小查找范围来逼近目标值。以下是二分算法的详细讲解&#xff1a; 基本原理 有序性&#xff1a;二分算法要求待搜索的数组必须是有序的&#xff08;…

在下游市场需求带动下 我国气调包装机市场规模逐渐扩大

在下游市场需求带动下 我国气调包装机市场规模逐渐扩大 气调包装机又称为气调保鲜包装机&#xff0c;是一种具有气体置换功能的保鲜包装设备。气调包装机的工作原理是将原有的包装内空气抽至真空&#xff0c;再充入一定配比的混合气体&#xff0c;从而对被包装的物品进行有效保…

ubuntu开机怎么进入、退出命令行界面

要在Ubuntu系统开机时进入命令行界面&#xff0c;可以按照以下步骤操作&#xff1a; 在开机过程中按下Ctrl Alt F1组合键&#xff0c;这将会切换到第一个虚拟控制台&#xff0c;即命令行界面。如果Ctrl Alt F1没有生效&#xff0c;也可以尝试Ctrl Alt F2、Ctrl Alt F3…