go中读写锁(rwmutex)源码解读实现原理
go读写锁的实现原理
1、RWMutex读写锁的概念
读写锁也就是我们所使用的RWMutex,其实是对于go本身的mutex做的一个拓展,当一个goroutine获得了读锁后,其他goroutine同样可以获得读锁,但是不能获得写锁。相反,当一个goroutine获得了写锁,其他goroutine既不能读也不能写,互斥的概念。
2、使用场景
适用于读多写少的情况
3、底层实现
读写锁实现的结构体位于src下的sync包下的rwmutex.go文件中
type RWMutex struct {w Mutex // held if there are pending writerswriterSem uint32 // semaphore for writers to wait for completing readersreaderSem uint32 // semaphore for readers to wait for completing writersreaderCount int32 // number of pending readersreaderWait int32 // number of departing readers
}
w字段代表着复用了互斥锁
writerSem代表写信号量,用于写等待读
readerSem代表读信号量,用于读等待写
readerCount代表当前执行读的goroutine数量
readerWait代表被阻塞的准备读的goroutine的数量
4、读锁的实现
加读锁
func (rw *RWMutex) RLock() {if atomic.AddInt32(&rw.readerCount, 1) < 0 {// A writer is pending, wait for it.runtime_SemacquireMutex(&rw.readerSem, false, 0)}
}
首先看这个if方法,为什么要判断小于0呢?
atomic.AddInt32(&rw.readerCount, 1) < 0调用的这个原子方法,目的就是当goroutine加读锁的时候读锁数量+1,如果返回的数量是负数,那么就代表了当前有其他写锁,这个时候就掉用runtime_SemacquireMutex方法休眠当前goroutine,readerSem就记录者这个goroutine。所以要判断是否小于0
释放读锁
// RUnlock undoes a single RLock call;
// it does not affect other simultaneous readers.
// It is a run-time error if rw is not locked for reading
// on entry to RUnlock.
func (rw *RWMutex) RUnlock() {if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 {// Outlined slow-path to allow the fast-path to be inlinedrw.rUnlockSlow(r)}
}
释放读锁的时候就是对readerCount读数量-1即可,如果返回值小于0,就代表着当前有写的操作,这个时候就会调用rUnlockSlow进入慢速通道
什么是慢速通道
func (rw *RWMutex) rUnlockSlow(r int32) {// A writer is pending.if atomic.AddInt32(&rw.readerWait, -1) == 0 {// The last reader unblocks the writer.runtime_Semrelease(&rw.writerSem, false, 1)}
}
被阻塞的准备读的goroutine数量-1,如果readerWait为0,就表示当前没有goroutine正在准备读,这个时候去唤醒写操作
5、写锁的实现
加写锁
const rwmutexMaxReaders = 1 << 30
// Lock locks rw for writing.
// If the lock is already locked for reading or writing,
// Lock blocks until the lock is available.
func (rw *RWMutex) Lock() {// First, resolve competition with other writers.rw.w.Lock()// Announce to readers there is a pending writer.r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders// Wait for active readers.if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {runtime_SemacquireMutex(&rw.writerSem, false, 0)}
}
写锁的调用就是调用互斥锁w的lock,如果计算之后还是有其他goroutine持有读锁,那么就调用runtime_SemacquireMutex休眠当前的goroutine等待所有的读操作完成, atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders这个操作目的是防止后面的goroutine拿到读锁,阻塞读的作用。
释放写锁
// Unlock unlocks rw for writing. It is a run-time error if rw is
// not locked for writing on entry to Unlock.
//
// As with Mutexes, a locked RWMutex is not associated with a particular
// goroutine. One goroutine may RLock (Lock) a RWMutex and then
// arrange for another goroutine to RUnlock (Unlock) it.
func (rw *RWMutex) Unlock() {// Announce to readers there is no active writer.r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)if r >= rwmutexMaxReaders {race.Enable()fatal("sync: Unlock of unlocked RWMutex")}// Unblock blocked readers, if any.for i := 0; i < int(r); i++ {runtime_Semrelease(&rw.readerSem, false, 0)}// Allow other writers to proceed.rw.w.Unlock()
}
当释放写锁的时候,首先会通过atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)恢复之前的写入的很大的那个负数,然后看当前有多少个读操作在等待,循环唤醒等待读的goroutine
注意:go中的锁不支持可重入锁,若想实现可自定义实现
6、总结
读写锁区分读锁和写锁,而普通的互斥锁不区分,读写锁主要应用在读多写少的场景,既保证了并发读的执行效率,又保证了线程之间的安全。
相关文章:
go中读写锁(rwmutex)源码解读实现原理
go读写锁的实现原理 1、RWMutex读写锁的概念 读写锁也就是我们所使用的RWMutex,其实是对于go本身的mutex做的一个拓展,当一个goroutine获得了读锁后,其他goroutine同样可以获得读锁,但是不能获得写锁。相反,当一个go…...
【人工智能】—_深度优先搜索、代价一致搜索、深度有限搜索、迭代深度优先搜索、图搜索
【人工智能】无信息搜索—BFS 、代价一致、DFS、深度受限、迭代深入深度优先、图搜索 什么是搜索 搜索问题是指既不能通过数学建模解决,又没有其他算法可以套用或者非遍历所有情况才能得出正确结果。这时就需要采用搜索算法来解决问题。搜索就是一种通过穷举所有解…...
uni-app 客服按钮可上下拖动动
项目需求: 因为悬浮客服有时候会遮挡住界面内容,故需要对悬浮的气泡弹窗做可拖动操作 movable-area:可拖动区域 movable-view:可移动的视图容器,在页面中可以拖拽滑动或双指缩放。 属性说明 属性名类型默认值说…...
基于Android的旅游管理系统 微信小程序
随着网络科技的发展,移动智能终端逐渐走进人们的视线,相关应用越来越广泛,并在人们的日常生活中扮演着越来越重要的角色。因此,关键应用程序的开发成为影响移动智能终端普及的重要因素,设计并开发实用、方便的应用程序…...
python-数据可视化-下载数据-CSV文件格式
数据以两种常见格式存储:CSV和JSON CSV文件格式 comma-separated values import csv filename sitka_weather_07-2018_simple.csv with open(filename) as f:reader csv.reader(f)header_row next(reader)print(header_row) # [USW00025333, SITKA AIRPORT, A…...
时序预测 | MATLAB实现SSA-XGBoost(麻雀算法优化极限梯度提升树)时间序列预测
时序预测 | MATLAB实现SSA-XGBoost(麻雀算法优化极限梯度提升树)时间序列预测 目录 时序预测 | MATLAB实现SSA-XGBoost(麻雀算法优化极限梯度提升树)时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 Matlab实现SSA-XGBoost时间序列预测,麻…...
leetcode 823 带因子的二叉树
用动态规划 如果两个节点值不同,要乘2,因为两个节点可以互换位置 dp[i] dp[left] * dp[right] * 2 如果相同 dp[i] dp[left] * dp[right] class Solution {public int numFactoredBinaryTrees(int[] arr) {Arrays.sort(arr);int n arr.length;long[] dp ne…...
钉钉消息已读、未读咋实现的嘞?
前言 一款app,消息页面有:钱包通知、最近访客等各种通知类别,每个类别可能有新的通知消息,实现已读、未读功能,包括多少个未读,这个是怎么实现的呢?比如用户A访问了用户B的主页,难道…...
Java 读取TIFF JPEG GIF PNG PDF
Java 读取TIFF JPEG GIF PNG PDF 本文解决方法基于开源 tesseract 下载适合自己系统版本的tesseract ,官网链接:https://digi.bib.uni-mannheim.de/tesseract/ 2. 下载之后安装,安装的时候选择选择语言包,我选择了中文和英文 3.…...
研磨设计模式day14模板方法模式
目录 场景 原有逻辑 有何问题 解决方案 解决思路 代码实现 重写示例 模板方法的优缺点 模板方法的本质 何时选用 场景 现在模拟一个场景,两个人要登录一个系统,一个是管理员一个是用户,这两个不同身份的登录是由后端对应的两个接…...
7 集群基本测试
1. 上传小文件到集群 在hadoop路径下执行命令创建一个文件夹用于存放即将上传的文件: [atguiguhadoop102 ~]$ hadoop fs -mkdir /input上传: [atguiguhadoop102 hadoop-3.1.3]$ hadoop fs -put wcinput/work.txt /input2.上传大文件 [atguiguhadoop1…...
chrono学习(一)
我想用chrono进行沙土的仿真,首先学习demo_GPU_ballCosim.cpp,这个例子仿真了一些沙土的沉降过程。 首先,运行编辑完成的文件demo_GPU_ballCosim: (base) eowyneowyn-MS-7D20:~/build_chrono/bin$ ./demo_GPU_ballCosim 运行完得…...
后端面试话术集锦第 十 篇:springMVC面试话术
这是后端面试集锦第十篇博文——springMVC面试话术❗❗❗ 1. 介绍一下springMVC springmvc是一个视图层框架,通过MVC模型让我们很方便的接收和处理请求和响应。 我给你说说他里边的几个核心组件吧: 它的核心控制器是DispatcherServlet,他的作用是接收用户请求,然后给用户…...
基于Django 框架搭建的机器学习在线平台源代码+数据库,实现KNN、ID3、C4.5、SVM、朴素贝叶斯、BP神经网络等算法及流程管理
结果展示(Kmeans): 完整代码下载地址:基于Django 框架搭建的机器学习在线平台源代码数据库 python机器学习之 K-邻近算法 简单的理解:[ 采用测量不同特征值之间的距离方法进行分类 ] 优点 :精度高、对异常…...
大数据组件-Flume集群环境搭建
🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…...
想系列服务迁移专有云效实操
想系列服务迁移专有云效实操 1注册应用 查看jenkins脚本是否需要修改代码编译路径 gemdale_jenkins/maven3-service/k8s-image/maven3-service-deploy.sh Jenkins上的打包路径 service_tgt_path s e r v i c e w s / t a r g e t / service_ws/target/ servicews/target/ser…...
2020 牛客多校第三场 C Operation Love (叉积判断顺逆时针)
2020 牛客多校第三场 (叉积判断顺逆时针) Operation Love 大意: 给出一个手型 , 每个手型都有 20 个点 ,手型有可能旋转后给出 , 但不会放大和缩小 . 手型点集有可能顺时针给出也可能逆时针给出 , 判断给出的是左手还…...
基于OFDM的水下图像传输通信系统matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 function [rx_img] func_TR(tx_img, num_path, pathdelays, pathgains, snr) rng(default); …...
Docsify + Gitalk详细配置过程讲解
💖 作者简介:大家好,我是Zeeland,开源建设者与全栈领域优质创作者。📝 CSDN主页:Zeeland🔥📣 我的博客:Zeeland📚 Github主页: Undertone0809 (Zeeland)&…...
React中的setState的执行机制
文章目录 前言setState是什么?更新类型批量更新后言 前言 在 React 中,setState 是用于更新组件状态的方法。它是一个异步操作 值得注意的是,由于 setState 是异步的,所以在调用 setState 后立即访问 this.state 可能得到的还是旧的状态值。…...
如何高效使用开源工具EnergyStarX提升Windows 11电池续航:完整实战指南
如何高效使用开源工具EnergyStarX提升Windows 11电池续航:完整实战指南 【免费下载链接】EnergyStarX 🔋 Improve your Windows 11 devices battery life. A WinUI 3 GUI for https://github.com/imbushuo/EnergyStar. 项目地址: https://gitcode.com/…...
Tencent Hunyuan3D-1.0学术合作机会:腾讯混元团队的研究方向与合作模式
Tencent Hunyuan3D-1.0学术合作机会:腾讯混元团队的研究方向与合作模式 【免费下载链接】Hunyuan3D-1 腾讯开源的Hunyuan3D-1项目,创新提出两阶段3D生成方法,实现快速、高质量的文本到3D和图像到3D转换,融合Hunyuan-DiT模型&#…...
Qwen3-8B镜像站新手教程:如何选择模型并进行首次提问
Qwen3-8B镜像站新手教程:如何选择模型并进行首次提问 1. 认识Qwen3-8B:你的智能AI助手 Qwen3-8B是Qwen系列最新一代大型语言模型,拥有80亿参数,在推理能力、指令执行和多语言支持方面表现出色。这个模型特别适合个人开发者和小型…...
ESP32驱动MT6826S磁编码器:从接线防烧到实时速度计算(附完整Arduino库)
ESP32与MT6826S磁编码器实战指南:安全接线与高效数据采集 1. 硬件连接:避开那些可能毁掉你项目的陷阱 MT6826S磁编码器作为一款高精度角度测量器件,在机器人关节控制、无人机云台稳定等场景中表现优异。但许多开发者第一次接触这款编码器时&a…...
别再只改yaml了!深入理解YOLOv5检测头:从P2到P5,如何根据你的目标大小选择最优组合?
深入解析YOLOv5多尺度检测头:从理论到实践的选择艺术 在计算机视觉领域,目标检测一直是核心任务之一。YOLO系列算法以其高效的检测速度和良好的精度表现,成为工业界和学术界的热门选择。然而,很多开发者在使用YOLOv5时,…...
RWKV7-1.5B-g1a参数调优教程:temperature=0.1稳输出 vs 0.8活生成,效果差异实测
RWKV7-1.5B-g1a参数调优教程:temperature0.1稳输出 vs 0.8活生成,效果差异实测 1. 模型简介 rwkv7-1.5B-g1a是基于RWKV-7架构的多语言文本生成模型,特别适合以下场景: 基础问答文案续写简短总结轻量中文对话 这个1.5B参数的版…...
终极指南:如何用智能工具轻松突破内容访问限制
终极指南:如何用智能工具轻松突破内容访问限制 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 内容访问突破工具是现代数字工作者的必备利器,它能帮助研究人员…...
Anything to RealCharacters效果评测:与Stable Diffusion ControlNet写实方案对比
Anything to RealCharacters效果评测:与Stable Diffusion ControlNet写实方案对比 1. 项目概述 Anything to RealCharacters是一款专为RTX 4090显卡优化的2.5D转真人图像转换系统。这个工具基于通义千问Qwen-Image-Edit-2511图像编辑底座,集成了专门的…...
VRCT终极指南:3步实现VRChat跨语言实时翻译,打破虚拟社交障碍
VRCT终极指南:3步实现VRChat跨语言实时翻译,打破虚拟社交障碍 【免费下载链接】VRCT VRCT(VRChat Chatbox Translator & Transcription) 项目地址: https://gitcode.com/gh_mirrors/vr/VRCT 您是否曾在VRChat的国际房间中,面对来自…...
intv_ai_mk11应用场景:技术团队内部知识沉淀助手、新人入职培训问答机器人
intv_ai_mk11应用场景:技术团队内部知识沉淀助手、新人入职培训问答机器人 1. 什么是intv_ai_mk11对话机器人 intv_ai_mk11是一款基于7B参数Llama架构的AI对话助手,专门为技术团队和新人培训场景设计。它运行在GPU服务器上,能够理解并回答各…...
