First reader and writers problem (讀者優先)
no reader be kept waiting unless a writer has obtain permission to write
semaphore rw=1, readcnt_m=1;
int readcnt=0;
Reader:
wait(readcnt_m);
readcnt++;
if(readcnt==1) wait(rw);
signal(readcnt_m);
read();
wait(readcnt_m);
readcnt--;
if(readcnt==0) signal(rw);
signal(readcnt_m);
Writer:
wait(rw);
write();
signal(rw);
readcnt_m 只是用來保護readcnt的數據一致性的,不必着重關注
rw相當於一個旗坑,要么插r表示在讀,要么插w表示在寫,插r只需要第一個人來插,最后一個走的人拔;插w表示在寫,每個在寫的人要單獨插
讀者來的時候判斷自己是不是第一個讀者,如果是它就必須搶 rw,因此 readcnt 的目的就是幫助讀者判斷自己是不是第一個讀者,或者最后一個走的讀者
這樣就實現了最多有一個人同時寫,但可以有多個人同時讀,讀和寫不能同時發生
Q1:進程 P 在寫,Q 可以讀?
此時 rw 在 P 手上,此時 readcnt=0,Q 來了要去搶 rw,顯然搶不到,所以阻塞
Q2:進程 P 在讀,Q 可以讀?
此時 readcnt>0,Q 不需要搶 rw,直接去讀了
No-Starve readers and writers problem (讀寫公平)
in the version above, the writers may starve
int readcnt=0;
semaphore readcnt_m=1;
semaphore write_m=1;
semaphore wfirst_m=1;
Writer:
wait(wfirst_m); // !
wait(write_m);
write();
signal(write_m);
signal(wfirst_m); // !
Read:
wait(wfirst_m); // !
signal(wfirst_m); // !
wait(readcnt_m);
readcnt++;
if(readcnt==1) wait(write_m);
signal(readcnt_m);
read();
wait(readcnt_m);
readcnt--;
if(readcnt==0) signal(write_m);
signal(readcnt_m);
we just add wfirst_m
寫者來了,如果寫不了(write_m
被讀者搶了),這時會把 wfirst_m
拿走,這樣至少沒有新的寫者可以進入
Second readers and writers problem (寫者優先)
once a writer is ready, the writer perform write as soon as possible
int readcnt=0;
semaphore readcnt_m=1;
semaphore read_m=1;
int writecnt=0;
semaphore writecnt_m=1;
semaphore write_m=1;
Writer:
wait(writecnt_m);
writecnt++;
if(writecnt==1) wait(read_m);
signal(writecnt_m);
wait(write_m);
write();
signal(write_m);
wait(writecnt_m);
writecnt--;
if(writecnt==0) signal(read_m);
signal(writecnt_m);
Reader:
wait(read_m);
wait(readcnt_m);
readcnt++;
if(readcnt==1) wait(write_m);
signal(readcnt_m);
signal(read_m);
read();
wait(readcnt_m);
readcnt--;
if(readcnt==0) signal(write_m);
signal(readcnt_m);
Q: 為什么上一個版本不是寫優先,而這個版本是?
寫者要訪問的時候會搶走 read_m,直到沒有寫者訪問時釋放……所以 read_m 的作用就是保證在有寫者在的時候沒有讀者可以執行