: 讀者寫者問題

來源:互聯網
上載者:User
多進程對共用資源互斥訪問及進程同步的經典問題 設有一檔案F,多個並發讀進程和寫進程都要訪問,要求:(1)讀寫互斥(2)寫寫互斥(3)允許多個讀進程同時訪問採用記錄型訊號量機制解決 較常見的寫法:semaphore fmutex=1, rdcntmutex=1;
//fmutex --> access to file; rdcntmutex --> access to readcount
int readcount = 0;
void reader(){
    while(1){
        wait(rdcntmutex);
        if(0 == readcount)wait(fmutex);
        readcount = readcount + 1;
        signal(rdcntmutex);
        //Do read operation ...
        wait(rdcntmutex);
        readcount = readcount - 1;
        if(0 == readcount)signal(fmutex);
        signal(rdcntmutex);
    }
}
void writer(){
    while(1){
        wait(fmutex);
        //Do write operation ...
        signal(fmutex);
    }
}讀進程只要看到有其他讀進程正在訪問檔案,就可以繼續作讀訪問;寫進程必須等待所有讀進程都不訪問時才能寫檔案,即使寫進程可能比一些讀進程更早提出申請。所以以上解法實際是 讀者優先 的解法。如果在讀訪問非常頻繁的場合,有可能造成寫進程一直無法訪問檔案的局面.... 為瞭解決以上問題,需要提高寫進程的優先順序。這裡另增加一個排隊訊號量:queue。讀寫進程訪問檔案前都要在此訊號量上排隊,通過區別對待讀寫進程便可達到提高寫進程優先順序的目的。另外再增加一個 writecount 以記錄提出寫訪問申請和正在寫的進程總數: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 訊號量,之後在真正做讀操作前即讓出(使得寫進程可以隨時申請到 queue)。而只有第一個寫進程需要申請 queue,之後就一直佔著不放了,直到所有寫進程都完成後才讓出。等於只要有寫進程提出申請就禁止讀進程排隊,變相提高了寫進程的優先順序。 通過類似思想即可實現讀寫進程的公平競爭:semaphore fmutex=1, rdcntmutex=1, queue=1;
//fmutex --> access to file; rdcntmutex --> access to readcount
int readcount = 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(queue);
        wait(fmutex);        signal(queue);
        //Do write operation ...
        signal(fmutex);    }
}讀進程沒變,寫進程變成在每次寫操作前都要等待 queue 訊號量。 課本上一般只會寫第一種解法吧。看了後兩種方法即可發現,在第一個解法中,fmutex 訊號量實際是雙重身份,首先實現對檔案的互斥訪問,其次起到了和後面排隊訊號量 queue 相同的作用,只不過在那種排序下只能是讀者優先。如果直接看過後兩種解法,應該會有更清楚的理解吧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.