写者优先模式
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
typedef struct
{
pthread_mutex_t mutex;
pthread_cond_t rw_cond_readers;
pthread_cond_t rw_cond_writers;
int waitreaders; //等待的读者数
int waitwriters; //等待的写者数
int refcount; //引用计数,等于-1表示写者在写
//大于等于0表示refcount个读者在读
}rwlock_t;
int rwlock_rdlock(rwlock_t* rw) //读者锁
{
int result;
result=pthread_mutex_lock(&rw->mutex);
if(result!=0)
return result;
while(rw->refcount<0||rw->waitwriters>0) //当写者在里面或者有等待的写者时,阻塞,因为有等待写者时阻塞,所以是写者优先模式
{
rw->waitreaders++;
result=pthread_cond_wait(&rw->rw_cond_readers,&rw->mutex);
rw->waitreaders--;
}
if(result==0)
rw->refcount++; //读者进入,临界区的读者数+1
pthread_mutex_unlock(&rw->mutex);
return result;
}
int rwlock_wrlock(rwlock_t* rw) //写者锁
{
int result;
result=pthread_mutex_lock(&rw->mutex);
if(result!=0)
return result;
while(rw->refcount!=0) //当临界区有写者或者临界区有读者时,阻塞
{
rw->waitwriters++;
result=pthread_cond_wait(&rw->rw_cond_writers,&rw->mutex);
rw->waitwriters--;
}
if(result==0)
rw->refcount=-1; //写者进入
pthread_mutex_unlock(&rw->mutex);
return result;
}
int rwlock_unlock(rwlock_t* rw) //释放锁
{
int result;
result=pthread_mutex_lock(&rw->mutex);
if(result!=0)
return result;
if(rw->refcount>0)
rw->refcount--; //读者在临界区
else if(rw->refcount==-1) //写者在临界区
rw->refcount=0;
if(rw->waitwriters>0) //通知写者可以进入
pthread_cond_signal(&rw->rw_cond_writers);
else if(rw->waitreaders>0) //通知读者可以进入
pthread_cond_broadcast(&rw->rw_cond_readers);
pthread_mutex_unlock(&rw->mutex);
return result;
}
rwlock_t rw={PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,0,0,0};
pthread_t tid1,tid2;
void* thread1(void*);
void* thread2(void*);
int main()
{
pthread_create(&tid1,NULL,thread1,NULL);
sleep(1);
pthread_create(&tid2,NULL,thread2,NULL);
pthread_join(tid2,NULL);
pthread_join(tid1,NULL);
printf("rw_refcount=%d,rw_waitreaders=%d,rw_waitwriters=%d\n",rw.refcount,rw.waitreaders,rw.waitwriters);
}
void* thread1(void* arg)
{
for(int i=0;i<10;i++)
{
rwlock_rdlock(&rw);
printf("thread1 got a read lock\n");
sleep(3);
rwlock_unlock(&rw);
}
return NULL;
}
void* thread2(void* arg)
{
for(int i=0;i<10;i++)
{
printf("thread2 trying to obtain a write lock\n");
rwlock_wrlock(&rw);
printf("thread2 got a write lock\n");
sleep(2);
rwlock_unlock(&rw);
}
return NULL;
}
下面是读者优先模式
int rwlock_rdlock(rwlock_t* rw)
{
int result;
result=pthread_mutex_lock(&rw->mutex);
if(result!=0)
return result;
while(rw->refcount<0) //这里是变化内容
{
rw->waitreaders++;
result=pthread_cond_wait(&rw->rw_cond_readers,&rw->mutex);
rw->waitreaders--;
}
if(result==0)
rw->refcount++;
pthread_mutex_unlock(&rw->mutex);
return result;
}
int rwlock_wrlock(rwlock_t* rw)
{
int result;
result=pthread_mutex_lock(&rw->mutex);
if(result!=0)
return result;
while(rw->refcount!=0||rw->waitreaders>0) //这里是变化内容,当有读者等待是,也阻塞
{
rw->waitwriters++;
result=pthread_cond_wait(&rw->rw_cond_writers,&rw->mutex);
rw->waitwriters--;
}
if(result==0)
rw->refcount=-1;
pthread_mutex_unlock(&rw->mutex);
return result;
}
int rwlock_unlock(rwlock_t* rw)
{
int result;
result=pthread_mutex_lock(&rw->mutex);
if(result!=0)
return result;
if(rw->refcount>0)
rw->refcount--;
else if(rw->refcount==-1)
rw->refcount=0;
if(rw->waitreaders>0) //这里是变化内容,更改通知顺序
pthread_cond_broadcast(&rw->rw_cond_readers);
else if(rw->waitwriters>0)
pthread_cond_signal(&rw->rw_cond_writers);
pthread_mutex_unlock(&rw->mutex);
return result;
}