互斥量和条件变量解决读者-写者问题

来源:互联网 发布:投影机融合软件 编辑:程序博客网 时间:2024/05/16 06:53

写者优先模式

#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;}
原创粉丝点击