信号量经典问题————读者写者不同优先级问题

读者写者问题

读写互斥,写写互斥,读读可并发

读者优先

  • 当读者写者都在等待时,只有所有读者都读完,写者才能写

信号量:w=1(可写),mutex=1(可读)
共享变量:rcount=0(读者数量)

//伪代码
int rcount=0
semaphore w=1,mutex=1
reader(){
    P(mutex);
    rcount++;
    if(rcount==1)
        P(w);//堵塞写者,保证所有读者读完
    V(mutex);
    //以上保证所有读者都可同时读
    //Read()
    P(mutex);
    rcount--;
    if(rcount==0)
        V(w);
    V(mutex);
}

writer(){
    P(w);
    //write()
    V(w);
}

存在问题,读者过多,饿死写者(rcount减少同时也在增加)。

写者优先

  • 写者读者都在等待时,只有所有写者写完后,读者才能获得读权限

增加wcount标记写者存在,如果同时存在读写者,读者在执行时通过P(w)阻塞写者,而写者wcount标记存在,通过P(r)防止读者继续加入。

P(x)与V(x)用以保护原子操作

int wcount=0,rcount=0;
semaphore w=1,r=1,x=1;
reader(){
    P(r);
    P(x);
    rcount++;
    if(rcount==1)
        P(w);
    V(x);
    V(r);
    //Read()
    P(x);
    rcount--;
    if(rcount==0)
        V(w);
    V(x);
}

writer(){
    P(x);
    wcount++;
    if(wcount==1)
        P(r);
    V(x);
    P(w);
    //Write()
    V(w);
    P(x);
    wcount--;
    if(wcount==0)
        V(r);
    V(x);
}
  • 对于写着优先问题,我也看了一些文章,觉得以下这个也很好

进程同步的经典问题1——读者写者问题(写者优先与公平竞争)
可以参考,这是代码

semaphore fmutex=1, rdcntmutex=1, wtcntmutex=1, queue=1;
//fmutex --> access to file; rdcntmutex --> access to readcount
//wtcntmutex --> access to writecount
int readcount = 0, writecount = 0;
void reader(){
    while(1){
        wait(queue);
        wait(rdcntmutex);
        if(0 == readcount)wait(fmutex);
        readcount = readcount + 1;
        signal(rdcntmutex);
        signal(queue);
        //Do read operation ...
        wait(rdcntmutex);
        readcount = readcount - 1;
        if(0 == readcount)signal(fmutex);
        signal(rdcntmutex);
    }
}
void writer(){
    while(1){
        wait(wtcntmutex);
        if(0 == writecount)wait(queue);
        writecount = writecount + 1;
        signal(wtcntmutex);
        wait(fmutex);
        //Do write operation ...
        signal(fmutex);
        wait(wtcntmutex);
        writecount = writecount - 1;
        if(0 == writecount)signal(queue);
        signal(wtcntmutex);
    }
}

增加一个排队信号量:queue。读写进程访问文件前都要在此信号量上排队,通过区别对待读写进程便可达到提高写进程优先级的目的。另外再增加一个 writecount 以记录提出写访问申请和正在写的进程总数.
每个读进程最开始都要申请一下 queue 信号量,之后在真正做读操作前即让出(使得写进程可以随时申请到 queue)。而只有第一个写进程需要申请 queue,之后就一直占着不放了,直到所有写进程都完成后才让出。等于只要有写进程提出申请就禁止读进程排队,变相提高了写进程的优先级。 

posted @ 2018-05-02 20:52  不知道的痛  阅读(3190)  评论(0编辑  收藏  举报