設有一文件F,多個并發讀進程和寫進程都要訪問,要求:
(1)讀寫互斥
(2)寫寫互斥
(3)允許多個讀進程同時訪問
采用記錄型信號量機制解決
?
較常見的寫法:

semaphore?fmutex = 1 ,?rdcntmutex = 1 ;
// fmutex?-->?access?to?file;?rdcntmutex?-->?access?to?readcount

int readcount = 0 ;
void
reader()
{
????
while ( 1
)
??? {
????????P(rdcntmutex);
????????
if (
readcount==0)
?????????? P(fmutex);
????????readcount
= readcount + 1
;
????????V(rdcntmutex);
????????
// Do?read?operation??

????????P(rdcntmutex);
????????readcount
= readcount - 1
;
????????
if (
readcount==0)
?????????? V(fmutex);
????????V(rdcntmutex);
????}
}
void
writer()
{
????
while ( 1
)
??? {
????????P(fmutex);
????????
// Do?write?operation?

????????V(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
)
??? {
????????P(queue);//申請隊列信號
????????P(rdcntmutex);//修改readcount,互斥
????????
if (
readcount==0)
??????????? P(fmutex);//access to file 互斥
????????readcount
= readcount + 1
;
????????V(rdcntmutex);//釋放
????????V(queue);//釋放
????????
// Do?read?operation?

????????P(rdcntmutex);
????????readcount
= readcount - 1
;
????????
if (
readcount==0)
??????????? V(fmutex);
????????V(rdcntmutex);
????}
}
void
writer()
{
????
while ( 1
)
??? {
????????P(wtcntmutex);
????????
if (
writecount==0)
??????????? P(queue);
????????writecount
= writecount + 1
;
????????V(wtcntmutex);
????????P(fmutex);
????????
// Do?write?operation?

????????V(fmutex);
????????P(wtcntmutex);
????????writecount
= writecount - 1
;
????????
if (
writecount==0)
??????????? V(queue);
????????V(wtcntmutex);
????}
}

?

每個讀進程最開始都要申請一下 queue 信號量,之后在真正做讀操作前即讓出(使得寫進程可以隨時申請到 queue)。而只有第一個寫進程需要申請 queue,之后就一直占著不放了,直到所有寫進程都完成后才讓出。等于只要有寫進程提出申請就禁止讀進程排隊,變相提高了寫進程的優先級。
?