信號量經典問題————讀者寫者不同優先級問題


讀者寫者問題

讀寫互斥,寫寫互斥,讀讀可並發

讀者優先

  • 當讀者寫者都在等待時,只有所有讀者都讀完,寫者才能寫

信號量: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,之后就一直占着不放了,直到所有寫進程都完成后才讓出。等於只要有寫進程提出申請就禁止讀進程排隊,變相提高了寫進程的優先級。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM