当前位置: 首页 > news >正文

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()}
http://www.lryc.cn/news/332584.html

相关文章:

  • 大数据实验统计-1、Hadoop安装及使用;2、HDFS编程实践;3、HBase编程实践;4、MapReduce编程实践
  • PyTorch搭建Informer实现长序列时间序列预测
  • firefox切换本地服务和全球服务的方法
  • Windows下用CMake编译PugiXML及配置测试
  • python-基础篇-字符串、列表、元祖、字典-列表
  • Qt控件样式设置其一(常见方法及优缺点)
  • 软件测试(测试用例详解)(三)
  • 最优算法100例之33-字符串/数字的排列组合问题
  • Java面试题:请解释Java中的多线程编程?
  • acwing算法提高之图论--最小生成树的扩展应用
  • 政安晨:【Keras机器学习实践要点】(十七)—— 利用 EfficientNet 通过微调进行图像分类
  • wordpress全站开发指南-面向开发者及深度用户(全中文实操)--php函数
  • Linux 设备驱动管理之内核对象(Kernel Object)机制
  • 【C语言】关键字选择题
  • 营销中的归因人工智能
  • ChatGPT 的核心 GPT 模型:探究其生成式预训练变换架构的革新与应用潜力
  • Python | Leetcode Python题解之第10题正则表达式匹配
  • 华大单片机新建工程步骤
  • 设计模式:桥接模式
  • 人脸识别:Arcface--loss+code
  • Linux-程序地址空间
  • adobe stock会员开通付费付款订阅充值教程/adobe stock免费白嫖一个月
  • Mysql的基本命令
  • leetcode.24. 两两交换链表中的节点
  • 后端开发框架Spring Boot快速入门
  • I2C驱动实验:验证所添加的I2C设备的设备节点
  • 160 Linux C++ 通讯架构实战14,epoll 反应堆模型
  • 根据mysql的执行顺序来写select
  • spring 和spring boot的区别
  • Day84:服务攻防-端口协议桌面应用QQWPS等RCEhydra口令猜解未授权检测