//具体参阅:《Unix网络编程》卷2,进程间通信。利用条件变量和互斥锁实现读写锁。
struct pthread_rwlock_t
{
pthread_mutex_t rw_mutex; //每一步获取读写锁,都要两次操作,上锁和解锁。每一步释放读写锁,也要两次操作,上锁和解锁。
pthread_cond_t rw_condreaders;
pthread_cond_t rw_condwritres;
int rw_magic;
int rw_nwaitreaders;//等待获取读锁的进程。
int rw_nwaitwriters;//等待获取写锁的进程。
int rw_refcount;//读写锁的当前状态,-1表示它是一个写入锁(任意时刻这样的锁只能有一个),为n(n>0)时,有n个进程正在同时读。
};
//以下是实现框架。大致思路日下:先判断当前状态rw_refcount和排队等待获取锁的waiters,再决定“获取锁”或者“加入等待,条件等待”.
//获取读锁
void pthread_rwlock_rdlock()
{
result=pthread_mutex_lock(&rw->rw_mutex);
while(rw->rw_refcount<0||rw->rw_nwaitwriters>0){
rw->rw_nwaitreaders++;
result=pthread_cond_wait(&rw->rw_condreaders,&rw->rw_mutex);
rw->rw_nwaitreaders--;
if(result!=0)
break;
}
if(result==0)
rw->rw_refcount++;
result=pthread_mutex_unlock(&rw->rw_mutex);
}
//获取写锁
void pthread_rwlock_rdlock()
{
result=pthread_mutex_lock(&rw->rw_mutex);
while(rw->rw_refcount!=0){
rw->rw_nwaitwriters++;
result=pthread_cond_wait(&rw->rw_condwritres,&rw->rw_mutex);
rw->rw_nwaitwriters--;
if(result!=0)
break;
}
if(result==0)
rw->rw_refcount=-1;
result=pthread_mutex_unlock(&rw->rw_mutex);
}
//释放读写锁。用一个统一释放函数即可。
void pthread_rwlock_rdlock()
{
result=pthread_mutex_lock(&rw->rw_mutex);
if(rw->rw_refcount>0)
rw->rw_refcount--;
else if(rw->rw_refcount==-1)
rw->rw_refcount=0;
else
throw error; //在释放锁时rw->rw_refcount=0判断条件的出现是不可能的,因为一旦加锁,它只可能两种状态,-1和1,2,3....
if(rw->rw_nwaitwriters>0)//为什么要先判断是否有等待写入者,因为如果有大量的读入者试图获取锁时,可能导致写入者永远无机会获取
if(rw->rw_refcount==0)
result=pthread_cond_signal(&rw->rw_condwritres);//一定要先给写入者机会,否则,写入者可能没机会获取锁。
else if(rw->rw_nwaitreaders>0)
result=pthread_cond_broadcast(&rw->rw_condreaders);
result=pthread_mutex_unlock(&rw->rw_mutex);
}
利用条件变量和互斥锁实现读写锁
最新推荐文章于 2021-08-17 22:27:48 发布