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