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

发布时间:2026/7/31 2:46:00
基于读写锁的读者写者问题 读者写者模式读写锁在编写多线程的时候有一种情况是十分常见的。那就是有些公共数据修改的机会比较少。相比较改写它们读的机会反而高的多。通常而言在读的过程中往往伴随着查找的操作中间耗时很长。给这种代码段加锁会极大地降低我们程序的效率。那么有没有一种方法可以专门处理这种多读少写的情况呢 有那就是读写锁。读者和读者之间无互斥关系可并行访问读者和写者之间是互斥关系一方操作时另一方必须等待写者和写者之间也是互斥关系。读写锁原理细节第一个到达的读者需要加锁阻止写者进入 后续新来的读者直接进入读取计数累加 最后一个读完的读者释放锁写者才有机会写入。读写锁接口设置读写优先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正在读的读者数量初值 0mutex保护 read_count 的互斥锁wrt读写共用锁写者占用后任何人都进不来执行逻辑读者到来先抢占 mutex 锁修改 read_count若自己是第一个读者抢占 wrt 锁锁住资源不让写者进来read_count释放 mutex开始读文件读者离开抢占 mutexread_count--若自己是最后一个读者释放 wrt 锁写者才有资格竞争资源释放 mutex写者到来 直接申请 wrt 锁拿不到就阻塞 只要还有读者在读wrt 永远不会释放写者持续等待。优缺点✅ 读者效率极高并发读取顺畅 ❌ 致命缺陷写者饥饿二写者优先核心思想一旦有写者等待资源后续所有新来的读者全部阻塞排队必须等所有等待 正在执行的写者全部完成后读者才能继续读。 杜绝写者饥饿但会出现读者饥饿。新增变量write_wait等待中的写者数目read_queue读者等待队列执行逻辑只要存在等待的写者拒绝所有新读者入场写者到达优先级 新来读者所有排队写者依次写完资源空闲后才放行积压的读者优缺点✅ 写者不会饿死写入响应快 ❌ 大量读者堆积等待读者饥饿三、公平读写队列先来先服务 FIFO无饥饿核心思想按照进程到达的先后顺序排队严格遵循先来后到排在队列首位的进程获得资源使用权若队首是读者连续放行队列里紧随其后的所有读者一起读若队首是写者只允许这一个写者独占资源写完才轮到下一批进程效果读者、写者地位均等既不会读者饥饿也不会写者饥饿整体吞吐最均衡。