設(shè)有一文件F,多個(gè)并發(fā)讀進(jìn)程和寫進(jìn)程都要訪問,要求:
(1)讀寫互斥
(2)寫寫互斥
(3)允許多個(gè)讀進(jìn)程同時(shí)訪問
采用記錄型信號(hào)量機(jī)制解決
?
較常見的寫法:
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);
????}
}
?
讀進(jìn)程只要看到有其他讀進(jìn)程正在訪問文件,就可以繼續(xù)作讀訪問;寫進(jìn)程必須等待所有讀進(jìn)程都不訪問時(shí)才能寫文件,即使寫進(jìn)程可能比一些讀進(jìn)程更早提出申請(qǐng)。所以以上解法實(shí)際是 讀者優(yōu)先 的解法。如果在讀訪問非常頻繁的場(chǎng)合,有可能造成寫進(jìn)程一直無法訪問文件的局面....
?
為了解決以上問題,需要提高寫進(jìn)程的優(yōu)先級(jí)。這里另增加一個(gè)排隊(duì)信號(hào)量:queue。讀寫進(jìn)程訪問文件前都要在此信號(hào)量上排隊(duì),通過區(qū)別對(duì)待讀寫進(jìn)程便可達(dá)到提高寫進(jìn)程優(yōu)先級(jí)的目的。另外再增加一個(gè) writecount 以記錄提出寫訪問申請(qǐng)和正在寫的進(jìn)程總數(shù):
?
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);//申請(qǐng)隊(duì)列信號(hào)
????????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);
????}
}
?
每個(gè)讀進(jìn)程最開始都要申請(qǐng)一下 queue 信號(hào)量,之后在真正做讀操作前即讓出(使得寫進(jìn)程可以隨時(shí)申請(qǐng)到 queue)。而只有第一個(gè)寫進(jìn)程需要申請(qǐng) queue,之后就一直占著不放了,直到所有寫進(jìn)程都完成后才讓出。等于只要有寫進(jìn)程提出申請(qǐng)就禁止讀進(jìn)程排隊(duì),變相提高了寫進(jìn)程的優(yōu)先級(jí)。
?