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

基于读写锁的读者写者问题

读者写者模式

读写锁

在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢? 有,那就是读写锁。
读者和读者之间无互斥关系,可并行访问;
读者和写者之间是互斥关系,一方操作时另一方必须等待;
写者和写者之间也是互斥关系。

读写锁原理细节:

第一个到达的读者需要加锁,阻止写者进入; 后续新来的读者直接进入读取,计数累加; 最后一个读完的读者释放锁,写者才有机会写入。

读写锁接口

设置读写优先

int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref); /* pref 共有 3 种选择 PTHREAD_RWLOCK_PREFER_READER_NP (默认设置) 读者优先,可能会导致写者饥饿情况 PTHREAD_RWLOCK_PREFER_WRITER_NP 写者优先,目前有 BUG,导致表现行为和 PTHREAD_RWLOCK_PREFER_READER_NP 一致 PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 写者优先,但写者不能递归加锁 */
初始化
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr);

销毁:

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
加锁和解锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

读者优先:

只要有读者正在读,后续新来的读者全都可以插队进入读取;写者会一直被阻塞,极易写者饥饿(写者迟迟得不到执行机会)。

共用基础变量:read_count:正在读的读者数量,初值 = 0mutex:保护 read_count 的互斥锁wrt:读写共用锁(写者占用后,任何人都进不来)

一、读者优先

核心思想

只要有读者正在读,后续新来的读者全都可以插队进入读取;写者会一直被阻塞,极易写者饥饿(写者迟迟得不到执行机会)。

共用基础变量:read_count:正在读的读者数量,初值 = 0

mutex:保护 read_count 的互斥锁

wrt:读写共用锁(写者占用后,任何人都进不来)

执行逻辑

  1. 读者到来:
    • 先抢占 mutex 锁,修改 read_count
    • 若自己是第一个读者:抢占 wrt 锁(锁住资源,不让写者进来)
    • read_count++,释放 mutex,开始读文件
  2. 读者离开:
    • 抢占 mutex,read_count--
    • 若自己是最后一个读者:释放 wrt 锁,写者才有资格竞争资源
    • 释放 mutex
  3. 写者到来: 直接申请 wrt 锁,拿不到就阻塞; 只要还有读者在读,wrt 永远不会释放,写者持续等待。

优缺点

✅ 读者效率极高,并发读取顺畅 ❌ 致命缺陷:写者饥饿

二:写者优先:

核心思想

一旦有写者等待资源,后续所有新来的读者全部阻塞排队;必须等所有等待 + 正在执行的写者全部完成后,读者才能继续读。 杜绝写者饥饿,但会出现读者饥饿

新增变量:write_wait:等待中的写者数目read_queue:读者等待队列

执行逻辑

  1. 只要存在等待的写者:拒绝所有新读者入场
  2. 写者到达优先级 > 新来读者
  3. 所有排队写者依次写完,资源空闲后,才放行积压的读者

优缺点

✅ 写者不会饿死,写入响应快 ❌ 大量读者堆积等待,读者饥饿

三、公平读写(队列先来先服务 FIFO,无饥饿)

核心思想

按照进程到达的先后顺序排队,严格遵循先来后到:

  1. 排在队列首位的进程获得资源使用权
  2. 若队首是读者:连续放行队列里紧随其后的所有读者一起读
  3. 若队首是写者:只允许这一个写者独占资源,写完才轮到下一批进程

效果

读者、写者地位均等,既不会读者饥饿,也不会写者饥饿,整体吞吐最均衡。

http://www.cnnetsun.cn/news/3758615.html

相关文章:

  • 游戏开发者日志解析:从武器设计到技术实现全流程
  • 685743
  • 每月省2小时:2026年3款荣耀实时转文字哪个好?实测选出高性价比款
  • 芯片与嵌入式系统开发:软件仿真、硬件仿真与原型验证全解析
  • 从Kafka到LLM:我们如何用流式日志构建反爬虫知识图谱
  • Adobe GenP 3.0技术深度解析:如何实现Adobe全家桶的智能激活方案
  • 5步掌握开源AI视频生成:从零到一的完整指南
  • C++20协程与Qt异步编程:QCoro库原理与实践指南
  • 大语言模型表征引导技术解析与实践
  • Unity 3D服装系统定制:模块化架构与性能优化实战
  • STM32标准库+FreeRTOS实现USB虚拟串口(CDC)完整移植指南
  • 物联网安全期末复习指南:从三层架构到9大核心考点解析
  • Go语言安全扫描实战:Gosec终极配置指南与CI/CD集成
  • 从游戏残局到团队协作:静音协作法解决信息过载
  • 告别Go GC!ClickHouse重构WAL-G,Rust让Postgres备份更高效
  • STM32驱动FM24CL64B FRAM:I2C接口高耐久存储实战指南
  • 中文情感分析数据集全攻略:从选型、评估到BERT实战应用
  • nfs服务器的相关知识
  • 阿里云发布“运维助手”:当两大云厂商同时押注运维AI,信号已经很明显了
  • STM32 GPIO实战:从LED闪烁到蜂鸣器驱动的嵌入式入门指南
  • IRIS OUT异常处理实战:图像边界检查与Python防御性编程
  • 调用限制与用量边界深度解析:以中国法定节假日API为例
  • 输入输出系统实战:字符设备、块设备与一切皆文件——公司的售前售后体系
  • 解密Palantir系列三:9.AIP · 从 Ontology 到 Agent,完整走一遍 AIP 工作流
  • 如何用Apollo Save Tool成为PS4存档管理大师:新手完全指南
  • 3个场景告诉你:为什么Windows用户需要Ext2Read这个Linux分区读取神器
  • Java字符串大小写转换的Locale问题与解决方案
  • 千人联名请愿调速、IPv6专项启动:GEO驶入“治理+可信”新航道
  • 智能车竞赛视觉导航:边线提取算法全解析与工程实践
  • 粉笔公考980多少钱正版与盗版的区别和风险