欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

读写问题---写者优先、公平竞争

程序员文章站 2022-07-05 09:04:17
...

允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个Writer进程和其他Reader进程或Writer进程同时访问共享对象,这样访问会引起混乱,此时读或写的区域就相当于一份临界资源。
所谓“读者-写者问题”是指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题。
对于访问区域这份临界资源就要通过锁来保护起来,任一时刻对区域进行的操作不会使数据文件混乱导致出错,即要保证临界资源的原子性。

首先做一下解释:
P()表示消耗一个信号量,在其它地方写的可能是wait()
V()是增加一个信号量,在其它地方可能写的是signal()

我们看第一种情况:读者优先

读者优先就是即使写者发出了请求写的信号,但是只要还有读者在读取内容,就还允许其他读者继续读取内容,直到所有读者结束读取,才真正开始写

semaphore write=1,mutex=1;
int readCount=0;

Writer(){
while(true)
P(mutex);   //互斥访问变量
if(readCount==0)       //如果是第一个读者,那么就禁止写文件
    P(write);
readCount++;
V(mutex);

*****
读取数据
*****
P(mutex);
readCount--;
if(readCount==0)          //如果是最后一个读者,那么此后就允许写文件
    V(write);
V(mutex);
}
}

Weader(){
while(true)
  P(write);
  *****
  写数据
  *****
  V(write);
}
}

我们看第二中情况:写者优先

写者优先的意思是:如果有写者申请写文件,那么在申请之前已经开始读取文件的可以继续读取,但是如果再有读者申请读取文件,则不能够读取,只有在所有的写者写完之后才可以读取

我们可以通过增加一个特权级队列来实现这个功能,一旦有写者申请写,那么后面的读者全部在特权及队列中排队

semphore write=1,mutex=1,queue=1;
int readCout=0,writeCount=0;

Reader(){
while(true){
P(queue);
if(readCount==0)
    P(write);
readCount++;
V(queue);

****
读取数据
****

P(mutex);
readCount--;
if(readCount==0)
    V(write);
V(mutex);
}
}


Writer(){
while(true){
P(mutex);
if(writeCount==0)
    P(queue);
writeCount++;
V(mutex);

P(write);
****
写数据
****
P(mutex);
writeCount--;
if(writeCount==0)
  V(queue);
V(mutex);
}
}

每个读进程在读取之前都申请一下queue,并且在申请成功读者数加一后就释放queue,但是第一个写进程申请的时候占据queue,后面的写进程无需 申请queue,直到所有的写进程结束后才释放queue,而在这期间,所有申请的读进程都在queue上排队,达到了写者优先的效果

同样的,我们可以实现公平竞争

我们看一下:公平竞争

semphore write=1,queue=1;

Reader(){
while(true)
P(write)
****
读取数据
****
V(write);
}
}


Writer(){
while(true)
P(write)
****
写数据
****
V(write);
}
}