操作系统要期末考了,读写问题之前一直弄不清楚,现在结合伪代码谈一下个人理解
读者优先
要求
读者优先问题:
- 允许多个读者读取;
- 读者在读的时候不能有写者在写;
- 不允许多个写者同时写;
- 如果写者申请写的时候有多个读者申请读,那么先读后写
分析
读者优先中,可以由多个写者和多个读者,那么需要用readercount和writercount记录
某时刻下存在的读者和写者数量,一旦存在读者/写者,立刻封锁startwr,直到所有count为0时再释放
需要使用以下信号量:
startwr:开启读/写进程
NowRW:现在是读者/写者的时间,可以控制Reader和Writer的顺序
Rmutex:使得多个读者依次进行
Wmutex:使得多个写者依次进行
伪代码
int Rmutex=0,Wmutex=0;
int RW=0,readercount=0,writercount=0;
int startrw=0;
void Reader(){
// 防止同时涌入多个Reader
wait(Rmutex);
readercount++;
if(readercount==1){
// 关键点
wait(RW);
}
signal(Rmutex);
// ---------------------
wait(startrw);
//start reading...
siganl(startrw);
// ---------------------
wait(Rmutex);
readercount--;
if(readercount==0){
signal(RW);
}
signal(Rmutex);
}
void Writer(){
// 防止同时涌入多个Writer
wait(Wmutex);
wait(RW);
writercount++;
if(writercount==1){
// 关键点
wait(startrw);
}
signal(RW);
signal(Wmutex);
// ---------------------
//start writing...
// ---------------------
wait(Wmutex);
writercount--;
if(writercount==0){
signal(startrw);
}
signal(Wmutex);
}
关键点
为什么if(writercount1)限制的是startwr,if(readercount1)限制的是NowRW?
原因是startwr只是限制读写操作的执行,NowRW可以控制reader和writer的添加。
我们设置一组测试用例:reader、writer、reader、reader、writer
按照代码,
1.首先reader进入,封锁NowRW,注意readercount变为1,所以后面的两个writer无法添加,直接添加后面两个reader;
2.三个reader依次进行读操作
3.两个writer依次进行写操作。读者优先效果达成;
写者优先
要求
写者优先问题:
1.允许多个读者读取;
2.读者在读的时候不能有写者在写;
3.不允许多个写者同时写;
4.如果读者申请读的时候已经有写者在写或申请写,那么所有写者写完之后读者才能读
分析
其实和读者优先问题差不多,需要用readercount和writercount记录某时刻下存在的读者和写者数量,一旦存在读者/写者,立刻封锁startwr,直到所有count为0时再释放
需要使用以下信号量:
startwr:开启读/写进程
NowRW:现在是读者/写者的时间,可以控制Reader和Writer的顺序
Rmutex:使得多个读者依次进行
Wmutex:使得多个写者依次进行
伪代码(和读者优先类似,只是更换关键点的位置)
int startwr = 0, NowRW = 0, Rmutex = 0, Wmutex = 0;
int readercount = 0, writercount = 0;
void Reader()
{
// 防止同时涌入多个Reader
wait(Rmutex);
// 进入读状态
wait(NowRW);
//prepare for reading...
readercount++;
if (readercount == 1)
{
wait(startwr);
}
signal(NowRW);
signal(Rmutex);
// -----------------------
// start reading...
readthings();
// -----------------------
wait(Rmutex);
readercount--;
if (readercount == 0)
{
// 说明所有Reader已经读完,可以开始写了
signal(startwr);
}
signal(Rmutex);
}
void Writer()
{
// 防止同时涌入多个Writer
wait(Wmutex);
writercount++;
if (writercount == 1)
{
wait(NowRW);
}
signal(NowRW);
signal(Wmutex);
// -----------------------
wait(startwr);
// start writing
writethings();
signal(startwr);
// -----------------------
wait(Wmutex);
writercount--;
if (writercount == 0)
{
signal(NowRW);
}
signal(Wmutex);
}
关键点
还是刚才那组测试用例:reader、writer、reader、reader、writer
按照代码,
1.首先reader进入,封锁NowRW,然后开始读,读之后释放NowRW;
2.然后writer进入,注意writercount变为1,所以后面的两个reader无法添加,直接添加最后一个writer
3.两个writer依次进行写操作;
4.最后的两个reader一次进行读操作