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 的作用就是保证在有写者在的时候没有读者可以执行