如何基于pthread基础原语实现简易读写锁?
用pthread基础原语实现简易读写锁
下面是基于pthread的互斥量(pthread_mutex_t)和条件变量(pthread_cond_t)实现的简易读写锁,完全使用基础原语构建,适合学习读写锁的核心逻辑:
1. 读写锁结构体定义
#include <pthread.h> typedef struct { pthread_mutex_t mutex; // 保护内部状态的互斥锁 pthread_cond_t read_cond; // 读者等待条件变量 pthread_cond_t write_cond; // 写者等待条件变量 int reader_count; // 当前活跃读者数量 int writer_active; // 是否有写者正在操作(1表示有,0表示无) } simple_rwlock_t;
2. 初始化与销毁函数
// 初始化读写锁 int simple_rwlock_init(simple_rwlock_t *rwlock) { int ret; if ((ret = pthread_mutex_init(&rwlock->mutex, NULL)) != 0) return ret; if ((ret = pthread_cond_init(&rwlock->read_cond, NULL)) != 0) { pthread_mutex_destroy(&rwlock->mutex); return ret; } if ((ret = pthread_cond_init(&rwlock->write_cond, NULL)) != 0) { pthread_cond_destroy(&rwlock->read_cond); pthread_mutex_destroy(&rwlock->mutex); return ret; } rwlock->reader_count = 0; rwlock->writer_active = 0; return 0; } // 销毁读写锁 int simple_rwlock_destroy(simple_rwlock_t *rwlock) { int ret; if ((ret = pthread_mutex_destroy(&rwlock->mutex)) != 0) return ret; if ((ret = pthread_cond_destroy(&rwlock->read_cond)) != 0) return ret; if ((ret = pthread_cond_destroy(&rwlock->write_cond)) != 0) return ret; return 0; }
3. 读锁定操作
// 获取读锁 int simple_rwlock_rdlock(simple_rwlock_t *rwlock) { int ret; if ((ret = pthread_mutex_lock(&rwlock->mutex)) != 0) return ret; // 等待当前写者完成操作 while (rwlock->writer_active) { if ((ret = pthread_cond_wait(&rwlock->read_cond, &rwlock->mutex)) != 0) { pthread_mutex_unlock(&rwlock->mutex); return ret; } } // 读者计数加1 rwlock->reader_count++; pthread_mutex_unlock(&rwlock->mutex); return 0; }
4. 读解锁操作
// 释放读锁 int simple_rwlock_rdunlock(simple_rwlock_t *rwlock) { int ret; if ((ret = pthread_mutex_lock(&rwlock->mutex)) != 0) return ret; rwlock->reader_count--; // 如果是最后一个读者,通知等待的写者 if (rwlock->reader_count == 0) { if ((ret = pthread_cond_signal(&rwlock->write_cond)) != 0) { pthread_mutex_unlock(&rwlock->mutex); return ret; } } pthread_mutex_unlock(&rwlock->mutex); return 0; }
5. 写锁定操作
// 获取写锁 int simple_rwlock_wrlock(simple_rwlock_t *rwlock) { int ret; if ((ret = pthread_mutex_lock(&rwlock->mutex)) != 0) return ret; // 等待所有读者完成,且没有活跃写者 while (rwlock->reader_count > 0 || rwlock->writer_active) { if ((ret = pthread_cond_wait(&rwlock->write_cond, &rwlock->mutex)) != 0) { pthread_mutex_unlock(&rwlock->mutex); return ret; } } // 标记写者正在操作 rwlock->writer_active = 1; pthread_mutex_unlock(&rwlock->mutex); return 0; }
6. 写解锁操作
// 释放写锁 int simple_rwlock_wrunlock(simple_rwlock_t *rwlock) { int ret; if ((ret = pthread_mutex_lock(&rwlock->mutex)) != 0) return ret; rwlock->writer_active = 0; // 先通知写者(写者优先),再通知所有等待的读者 if ((ret = pthread_cond_signal(&rwlock->write_cond)) != 0) { pthread_mutex_unlock(&rwlock->mutex); return ret; } pthread_cond_broadcast(&rwlock->read_cond); pthread_mutex_unlock(&rwlock->mutex); return 0; }
核心逻辑说明
- 互斥锁:用于保护读写锁内部的
reader_count和writer_active变量,确保状态修改的原子性。 - 条件变量:
read_cond供读者等待写者完成,write_cond供写者等待所有读者/其他写者完成。 - 优先级调整:当前实现默认读者优先,若要改为写者优先,可添加
writer_waiting计数,调整等待条件优先唤醒写者。 - 虚假唤醒处理:所有条件变量的等待都嵌套在
while循环中,避免系统虚假唤醒导致的逻辑错误。
内容的提问来源于stack exchange,提问作者Guy Avraham
相关产品推荐
相关产品推荐

