首页/操作系统/02-process/读者写者问题详解 🔗 在 Obsidian 中打开
操作系统 · 02-process

读者写者问题详解

重要度 ★★ 读者写者读写锁读者优先写者优先饥饿
速查
多个读者和写者共享一个文件:读-读允许,读-写互斥,写-写互斥。需要 rw=1(读写互斥)、mutex=1(保护 count)、count(读者数)。读者优先可能饿死写者。

速查

多个读者和写者共享一个文件(数据库):

  • 读者:只读,可多个同时读
  • 写者:读写,必须独占访问
  • 约束:①读-读允许 ②读-写互斥 ③写-写互斥
名称初值含义
rw1读写互斥信号量
mutex1保护 count 变量
count0当前正在读的读者数

核心概念

读者优先方案(写者可能饥饿):

写者:P(rw); 写文件; V(rw)
读者:P(mutex); count++; if(count==1) P(rw); V(mutex);
      读文件;
      P(mutex); count--; if(count==0) V(rw); V(mutex)

写者优先方案:增加信号量 w=1,写者到来时先 P(w) 阻止新读者进入,避免写者饥饿。

特性读者优先写者优先
读者并发高,可能无限加入受限,写者等待时新读者阻塞
写者饥饿可能不会
信号量数量2 + count3 + count

手算示例

读者优先,初始 $rw=1, mutex=1, count=0$,到达顺序 R1, R2, W1, R3:

步骤操作rwmutexcount说明
1–4R1 加锁文件011第一个读者锁 rw
6–9R2 加入012R1、R2 同时读
10W1 P(rw)-112W1 阻塞
11–13R3 也能加入-113R3 开始读

写者 W1 被读者们"饿"住——这就是读者优先的饥饿问题。

count 保护必要性 若不用 mutex 保护 count:R1、R2 并发 count++ 都读到 0 写回 1,实际 2 读者却记成 1;R1 结束时 count--→0 会错误地 V(rw),导致写者混入→互斥被破坏

易错点

注意
  • 读者写者允许多个读者同时访问,与生产者消费者全互斥不同
  • count 必须用 mutex 保护,否则并发修改破坏互斥
  • 读者优先:count>0 时新读者可无限加入→写者饥饿
  • 写者优先:靠额外信号量 w 阻止新读者
  • 不能仅用一个信号量实现(需 count 跟踪读者数)

核心结论

必背
  1. 读者写者核心是"读写锁"思想:读-读并发,读-写/写-写互斥
  2. count 记录读者数,第一个读者加锁、最后一个读者解锁
  3. mutex 保证 count 的修改是原子的
  4. 读者优先可能饿死写者;写者优先用 w 信号量防止
  5. 仅用一个互斥信号量无法实现(无法区分首读者/后续读者)

记忆卡片

与生产者消费者核心区别?
生产者消费者全互斥;读者写者允许多读者并发,仅写者独占。
count 的作用?为何需 mutex?
count 记录读者数;首读者加锁、末读者解锁。mutex 保证 count 原子修改。
为何读者优先饿写者?
count>0 时新读者不断加入,写者 P(rw) 一直无法通过,直到所有读者退出。
写者优先如何防饥饿?
增加 w 信号量:写者持 w 时新读者在 P(w) 阻塞,不无限加入。
能否一个信号量实现?
不能。需用 count 跟踪读者数配合额外信号量。

交互动画 · 读者计数与写者饥饿

共享文件 rw=1 读者(count=0) 写者
点击「读者进入」观察 count 增长、首个读者锁文件;「写者进入」在读者在场时会被阻塞(读者优先饥饿)
读-读允许;读-写/写-写互斥。count 用 mutex 保护

相关知识点

producer-consumer dining-philosophers process-synchronization-semaphore monitor

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。