读写问题---写者优先、公平竞争
程序员文章站
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);
}
}
下一篇: Elasticsearch 5.x 性能