操作系统——读者-写者问题的解决方法

参考博客:https://blog.csdn.net/c1194758555/article/details/52805918
https://www.cnblogs.com/wkfvawl/p/11538431.html

问题描述

不允许Write进程和Read进程或其他Write进程同时访问文件,Read进程可以和其他Read进程同时访问。
分为三种类型。

读者优先

要求:
1.多个读者可以同时访问文件
2.同一时间只允许一个写者访问文件
3.读者和写者进程互斥
解决方法:
用一个readcounter记录是第几个读者在读,如果是第一个读者,则不能让写者写,需要一个锁。因为readcounter是临界资源,也需要一个互斥量。

semaphore rc_mutex = 1, wmutex = 1;
readcounter = 0;

void writer{
    do{
        wait(wmutex);
        //write
        signal(wmutex);
    }while(TRUE);
}

void reader{
    do{
        wait(rc_mutex);
        if(readcounter == 0)    wait(wmutex);
        readcounter ++;
        signal(rc_mutex);
        
        // read
        wait(rc_mutex);
        readcounter --;
        if(!readcounter)    signal(wmutex);
        signal(rc_mutex);
    }while(TRUE);
}

写者优先

要求:
1.读者写者互斥
2.写者读者同时等待时,所有等待的写者优先,等所有写者结束后,读者才能读
3.没有写者时,读者能同时读
4.写者到来时,不会终止已经进行的读者操作
解决方法:

semaphore rc_mutex = 1, wmutex = 1;
semaphore wc_mutex = 1, prior = 1;  //写者计数器,优先信号量
readcounter = 0, writercounter = 0;

void writer{
    do{
        wait(wc_mutex); //申请更改wc的权限
        if(writercounter == 0)  //如果是第一个写者,就申请优先权限
            wait(prior);    
        writercounter ++;
        signal(wc_mutex);
        
        wait(wmutex); 
        //write
        signal(wmutex);
        
        wait(wc_mutex);
        writercounter --;
        if(!writercounter)
            signal(prior);  //当最后一个写者操作完成后,释放优先级权限
        signal(wc_mutex);
    }while(TRUE);
}

void reader{
    do{
        wait(prior);    //先申请优先级权限,如果前面还有写者就等待
        wait(rc_mutex);
        if(readcounter == 0)    wait(wmutex);
        readcounter ++;
        signal(rc_mutex);
        signal(prior);  //释放优先级权限
        
        // read
        wait(rc_mutex);
        readcounter --;
        if(!readcounter)    signal(wmutex);
        signal(rc_mutex);
        
    }while(TRUE);
}

读写均等

semaphore rc_mutex = 1, wmutex = 1;
semaphore prior = 1;  //读者和写者都等待在一个队列上,实现读写均等
readcounter = 0, writercounter = 0;

void writer{
    do{
        wait(prior);
        wait(wmutex);
        //write
        signal(wmutex);
        signal(prior);
    }while(TRUE);
}

void reader{
    do{
        wait(prior);
        wait(rc_mutex);
        if(readcounter == 0)    wait(wmutex);
        readcounter ++;
        signal(rc_mutex);
        signal(prior);
        
        //read
        wait(rc_mutex);
        readcounter --;
        if(!readcounter)    signal(wmutex);
        signal(rc_mutex);
        
    }while(TRUE);
}

有错误请指出!

posted @ 2021-10-12 21:09  inss!w!  阅读(514)  评论(0编辑  收藏  举报