请求:实现Readers-writers问题的无死锁伪代码(每写者配5读者)
读者-写者问题:带写者等待时的读者限流算法
核心逻辑
- 无写者等待时,允许任意数量读者同时访问数据库
- 有写者等待时,最多允许 5 × 等待写者数 的读者同时活跃,既避免写者长期饥饿,又控制读者数量降低死锁风险
- 通过互斥锁保护共享计数器,用信号量协调数据库的独占/共享访问权限
伪代码实现
共享变量
int active_readers = 0 // 当前正在访问的读者数量 int waiting_writers = 0 // 等待访问的写者数量 semaphore mutex = 1 // 保护共享变量的互斥锁 semaphore db_access = 1 // 控制数据库访问:写者独占,读者共享 semaphore reader_turn = 1 // 协调读者与写者的排队顺序,避免死锁与饥饿
读者线程流程
读者线程执行步骤: 1. P(reader_turn) // 获取读者轮次锁,确保调度公平性 2. P(mutex) a. 若 waiting_writers == 0: - active_readers += 1 - 若 active_readers == 1: P(db_access) // 第一个读者抢占数据库权限,阻止写者进入 b. 否则: - 若 active_readers < 5 * waiting_writers: active_readers += 1 - 若 active_readers == 1: P(db_access) - 否则: V(mutex) V(reader_turn) 返回步骤1重新尝试 // 超过读者限额,等待写者处理后再排队 3. V(mutex) 4. V(reader_turn) 5. 执行数据库读取操作... 6. P(mutex) a. active_readers -= 1 b. 若 active_readers == 0: V(db_access) // 最后一个读者释放数据库权限,允许写者进入 7. V(mutex)
写者线程流程
写者线程执行步骤: 1. P(mutex) a. waiting_writers += 1 2. V(mutex) 3. P(db_access) // 等待数据库空闲(无读者/其他写者) 4. P(mutex) a. waiting_writers -= 1 5. V(mutex) 6. 执行数据库写入操作... 7. V(db_access) 8. V(reader_turn) // 唤醒等待的读者,让其重新检查进入条件
关键说明
mutex严格保护共享计数器的修改,避免竞态条件reader_turn防止读者无限抢占导致写者饥饿,同时确保写者完成后读者能及时重新评估进入资格- 写者等待时的读者限额(5×等待写者数)平衡了读者并发效率与写者的响应速度
内容的提问来源于stack exchange,提问作者AstroD_
相关产品推荐
相关产品推荐

