Go 源码之读写锁 sync.RWMutex
Go 源码之读写锁 sync.RWMutex
文章目录
- Go 源码之读写锁 sync.RWMutex
- 一、简介
- 二、源码
- (一)RWMutex数据结构
- (二)Lock
- (三)Unlock
- (四)TryRLock
- (五)Rlock
- (六)RUnlock
- 三、常见问题
- 1. 什么是CAS,什么是原子操作
- 2. 写操作是如何阻止写操作的
- 3. 写操作是如何阻止读操作的
- 4. 读操作是如何阻止写操作的
- 5. 为什么写锁定不会被饿死
- 总结
- 参考资料
一、简介
sync.RWMutex 是 Go 语言标准库中的读写锁。
读写锁允许同时存在读锁和写锁。读锁可以被多个线程同时持有,而写锁在任何时候只能被一个线程持有。
sync.RWMutex 的主要作用:是在多线程环境下提供对共享资源的读/写访问控制,以提高并发性能。
它的一些主要方法包括:
- Lock:获取写锁。
- RLock:获取读锁。
- Unlock:释放锁。
使用读写锁的好处是,在多读少写的场景下,可以提高并发性能,因为读操作不会相互阻塞。
在使用 sync.RWMutex 时,需要注意以下几点:
- 确保在适当的时候释放锁,以避免死锁。
- 避免在持有锁的情况下进行耗时操作。
- 尽量减少锁的持有时间
二、源码
(一)RWMutex数据结构
type RWMutex struct {w Mutex // 写锁writerSem uint32 // 缓冲信号量,获取写锁的阻塞等待信号队列readerSem uint32 // 缓冲信号量,获取读锁的阻塞等待信号队列readerCount int32 // 当前持有读锁的 goroutine 数量,负数表示有个写锁在执行readerWait int32 // 获取写锁时,如果之前还有 readerWait 数量的读锁在执行,则需要等待执行完才能获取写锁
}
字段说明:
-
w
写锁
-
writerSem
缓冲信号量,当有goroutine获取写锁时,如果当前有读锁在占有,则调用 runtime_SemacquireMutex(&rw.writerSem, false, 0)
将当前goroutine进行睡眠,并排队到 writerSem 队列的队尾,等待所有的读锁释放之后再调用runtime_Semrelease(&rw.writerSem, false, 1)进行唤醒
-
readerSem
缓冲信号量,当有goroutine获取读锁时,如果当前有写锁在占有(readerCount),则调用 runtime_SemacquireMutex(&rw.readerSem, false, 0),将当前goroutine进行睡眠,并排队到 readerSem 队列的队尾,等待写锁释放之后再调用runtime_Semrelease(&rw.readerSem, false, 0)进行唤醒
-
readerCount
当前持有读锁的goroutine数量,负数表示有个写锁在执行,在获取写锁时,会将readerCount-rwmutexMaxReaders变为负数
写锁释放后readerCount会再+rwmutexMaxReaders变为正数
-
readerWait
首先读锁是会阻塞写锁的获取的,当一个goroutine尝试去获取一个写锁时,会将当前持有读锁的数量readerCount赋值给readerWait,表示当前goroutine要等待readerWait个goroutine释放读锁之后才能成功获取写锁
(二)Lock
// 获取写锁,会等待所有的读锁释放
func (rw *RWMutex) Lock() {if race.Enabled {_ = rw.w.staterace.Disable()}相关文章:
Go 源码之读写锁 sync.RWMutex
Go 源码之读写锁 sync.RWMutex 文章目录 Go 源码之读写锁 sync.RWMutex一、简介二、源码(一)RWMutex数据结构(二)Lock(三)Unlock(四)TryRLock(五)Rlock(六)RUnlock三、常见问题1. 什么是CAS,什么是原子操作2. 写操作是如何阻止写操作的3. 写操作是如何阻止读操作的…...
大数据实验统计-1、Hadoop安装及使用;2、HDFS编程实践;3、HBase编程实践;4、MapReduce编程实践
大数据实验统计 1、Hadoop安装及使用; 一.实验内容 Hadoop安装使用: 1)在PC机上以伪分布式模式安装Hadoop; 2)访问Web界面查看Hadoop信息。 二.实验目的 1、熟悉Hadoop的安装流程。 2、…...
PyTorch搭建Informer实现长序列时间序列预测
目录 I. 前言II. InformerIII. 代码3.1 输入编码3.1.1 Token Embedding3.1.2 Positional Embedding3.1.3 Temporal Embedding 3.2 Encoder与Decoder IV. 实验 I. 前言 前面已经写了很多关于时间序列预测的文章: 深入理解PyTorch中LSTM的输入和输出(从i…...
firefox切换本地服务和全球服务的方法
方法1:“设置”>“同步">“切换全球/本地服务器” https://jingyan.baidu.com/article/1974b2898523bbb5b1f774e2.html 方法2:地址栏输入about:config,搜索首选项名称里输入identity.fxaccounts.autoconfig.uri,填入…...
Windows下用CMake编译PugiXML及配置测试
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 PugiXML是什么? PugiXML 是一个用于解析和操作 XML 文档的 C 库。它提供了简单易用的接口,能够高效地加载…...
python-基础篇-字符串、列表、元祖、字典-列表
文章目录 2.3.2列表2.3.2.1列表介绍2.3.2.1.1列表的格式2.3.2.1.2打印列表 2.3.2.2列表的增删改查2.3.2.2.1列表的遍历2.3.2.2.1.1使用for循环2.3.2.2.1.2使用while循环 2.3.2.2.2添加元素("增"append, extend, insert)2.3.2.2.2.1append 2.3.2.2.2.2extend2.3.2.2.2…...
Qt控件样式设置其一(常见方法及优缺点)
如果你对Qt有基本的了解,应该知道它的一大优点是跨平台,可以在不同的系统中编译运行。但在我看来,Qt还有另外一个优点,就是制作界面比较方便和灵活,能够实现主流静态效果的桌面应用。(如果需要实现比较灵动…...
软件测试(测试用例详解)(三)
1. 测试用例的概念 测试用例(Test Case)是为了实施测试而向被测试的系统提供的一组集合。 测试环境操作步骤测试数据预取结果 测试用例的评价标准: 用例表达清楚,无二义性。。用例可操作性强。用例的输入与输出明确。一条用例只有…...
最优算法100例之33-字符串/数字的排列组合问题
专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 字符串/数字的排列组合问题 void dfs(int deep){if(deep == n){//输出}for(int i = 0; i < n; i++){if(flag[i] == 0){d[d…...
Java面试题:请解释Java中的多线程编程?
Java中的多线程编程允许 concurrently 执行多个线程,从而可以同时执行多个任务,提高程序的效率和响应性。在Java中,线程可以通过以下两种主要方式来实现: 继承 Thread 类实现 Runnable 接口 继承 Thread 类 class MyThread ext…...
acwing算法提高之图论--最小生成树的扩展应用
目录 1 介绍2 训练 1 介绍 本专题用来记录使用最小生成树算法(prim或kruskal)解决的扩展题目。 2 训练 题目1:1146新的开始 C代码如下, #include <iostream> #include <cstring> #include <algorithm>usin…...
政安晨:【Keras机器学习实践要点】(十七)—— 利用 EfficientNet 通过微调进行图像分类
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 本文目标: 使用 EfficientNet 和在图…...
wordpress全站开发指南-面向开发者及深度用户(全中文实操)--php函数
php函数 wordpress会封装一部分函数,比如bloginfo该函数的作用是直接调用你设置的你的网站的名称 示例 This is our amazing custom theme <?php echo 22; function myfirstfunction(){ echo 33; echo "<p>Hello ,this is my first function</…...
Linux 设备驱动管理之内核对象(Kernel Object)机制
Linux 设备驱动管理之内核对象(Kernel Object)机制 Linux内核是一个复杂的系统,它通过一系列的机制和结构体来管理和表示系统中的资源。其中一个关键的概念是“内核对象”(Kernel Object,简称kobject)。本文将深入探讨kobject机制…...
【C语言】关键字选择题
前言 题目一: 题目二: 题目三: 题目四: 题目五: 题目六: 前言 关于C语言关键字相关的选择题 题目一: 用在switch语言中的关键字不包含哪个?( ) A .continue B .break C .defa…...
营销中的归因人工智能
Attribution AI in marketing 归因人工智能作为智能服务的一部分,是一种多渠道算法归因服务,根据特定结果计算客户互动的影响和增量影响。有了归因人工智能,营销人员可以通过了解每个客户互动对客户旅程每个阶段的影响来衡量和优化营销和广告…...
ChatGPT 的核心 GPT 模型:探究其生成式预训练变换架构的革新与应用潜力
GPT(Generative Pre-trained Transformer)模型是一种深度学习模型,由OpenAI于2018年首次提出,并在随后的几年中不断迭代发展,包括GPT-2、GPT-3以及最新的GPT-4。GPT模型在自然语言处理(NLP)领域…...
Python | Leetcode Python题解之第10题正则表达式匹配
题目: 题解: class Solution:def isMatch(self, s: str, p: str) -> bool:m, n len(s), len(p)dp [False] * (n1)# 初始化dp[0] Truefor j in range(1, n1):if p[j-1] *:dp[j] dp[j-2]# 状态更新for i in range(1, m1):dp2 [False] * (n1) …...
华大单片机新建工程步骤
1.新建文件夹,比如00_LED 2.拷贝 hc32f460_ddl_Rev2.2.0\driver 到 00_LED 3.拷贝 hc32f460_ddl_Rev2.2.0\mcu\common 到 00_LED 4.拷贝 hc32f460_ddl_Rev2.2.0\example\ev_hc32f460_lqfp100_v2\gpio\gpio_output\source 到 00_LED 5.拷贝 hc32f460_ddl_Rev2.2.…...
设计模式:桥接模式
定义 桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象与实现分离,使它们可以独立地变化。在桥接模式中,抽象部分(Abstraction)包含对实现部分(Implementor)的引用,实现部分可以通过接口中的方法被抽象部分使用,但是具体的实现细节对于抽象部分来说是隐藏的…...
火山引擎AgentKit实战:从零构建企业级AI智能体应用
1. 从零到一:AgentKit代码工坊深度解析与实战指南如果你正在寻找一个能快速上手、功能强大的企业级AI Agent开发平台,那么火山引擎的AgentKit绝对值得你花时间深入研究。最近,我花了大量时间泡在它的官方代码示例仓库bytedance/agentkit-samp…...
电动汽车充电站控制系统的Intel处理器实践与优化
1. 电动汽车充电站的技术架构解析电动汽车充电站作为新型能源基础设施的核心节点,其技术实现远比传统加油站复杂。一个完整的充电站系统通常包含三个层级:电力转换模块(AC/DC)、控制管理系统(CMS)和云端服务…...
魔兽争霸III终极优化指南:WarcraftHelper让你的游戏体验焕然一新
魔兽争霸III终极优化指南:WarcraftHelper让你的游戏体验焕然一新 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper WarcraftHelper是一款专为…...
从一次内存拷贝崩溃说起:手把手教你用memcpy_s重构老旧C代码
从内存越界崩溃到安全重构:实战memcpy_s迁移指南 调试器突然停止在memcpy调用处,控制台抛出"Segmentation fault"的那一刻,每个C语言开发者都会心头一紧。这种由内存越界引发的崩溃在遗留代码库中尤为常见,就像我去年接…...
从TTP223到JL523:低成本电容触摸按钮的选型与实战
1. 电容触摸按钮入门:从原理到选型 第一次接触电容触摸按钮是在五年前的一个智能台灯项目上。当时为了给台灯添加一个酷炫的触摸开关,我试遍了市面上各种方案,最终锁定了TTP223这颗经典芯片。没想到几年后,国产的JL523给了我更大的…...
openclaw gateway网关运行详解
📘 Gateway 网关运行手册 — 关键内容与操作流程 1) Gateway 是什么 Gateway 网关服务 是一款长期运行的进程,用于处理连接控制、事件平面,与底层 Baileys / Telegram 等协议对接,为客户端提供 RPC/HTTP 接口。它自身启动后持续运…...
DS4Windows完全指南:让你的PS4手柄在Windows上大放异彩 [特殊字符]
DS4Windows完全指南:让你的PS4手柄在Windows上大放异彩 🎮 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 还在为PC游戏不支持PS4手柄而烦恼吗?想要在W…...
从A*到平滑:拉绳算法如何为游戏角色“剪裁”最优路径
1. 游戏寻路为什么需要平滑处理? 想象一下你在玩一款开放世界游戏,控制角色从城堡出发前往远处的森林。如果直接使用A*算法生成的路径,角色可能会像喝醉酒一样左右摇摆,贴着导航网格的边缘移动。这种"锯齿状路径"不仅看…...
终于蹲到了!“能读一半就是赚到”的《编码》精装版来了
前言:介绍一本好书 《编码》的第1版出版于1999年9月,从非常简单的概念开始讲解计算机工作的基础原理,帮助零基础的读者理解计算机的底层逻辑,建立计算机世界观。出版后立即收获全球范围内的广泛好评,成为影响几代程序员…...
设计系统文本化:用YAML/JSON统一管理设计令牌,实现多端一致与自动化
1. 项目概述:当设计系统遇上纯文本 最近在跟一个跨职能团队协作时,我们遇到了一个典型的老大难问题:设计师在Figma里更新了一个按钮的主色调,前端工程师在代码库里改了对应的CSS变量,但负责撰写产品文档和营销材料的同…...
