读者/写者问题
读者与写者问题(reader-writer problem)(Courtois, 1971)是经典的并发程序设计问题。在这个问题中,我们有两组进程:读者(Readers)和写者(Writers),它们需要共享访问一个文件 F 。
读者优先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| semaphore rmutex = 1; semaphore wmutex = 1; int read_count = 0;
process reader_i() { while (true) { P(rmutex); if (read_count == 0) P(wmutex); ++read_count; V(rmutex); read(); P(rmutex); if (--read_count == 0) V(wmutex); V(rmutex); } }
process writer_i() { while (true) { P(wmutex); write(); V(wmutex); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| semaphore rmutex = 1; semaphore wmutex = 1; semaphore rwmutex = 1; int read_count = 0;
process reader_i() { while (true) { P(rmutex); if (read_count == 0) P(wmutex); ++read_count; V(rmutex); read(); P(rmutex); if (--read_count == 0) V(wmutex); V(rmutex); } }
process writer_i() { while (true) { P(rwmutex); P(wmutex); write(); V(wmutex); V(rwmutex); } }
|
在上述算法中引入了新的信号量rwmutex,用于阻塞后来的写者。重新设计的算法可以保证:任何一个读者到来时,没有任何后来者正在对wmutex排队。因此,当前使用wmutex的进程结束之后,该读者可以马上开始工作。即,后来的读者可以对先来的写者插队。
原文:再论“读者优先”
写者优先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| int read_count = 0, write_count = 0; semaphore x = 1, y = 1, z = 1; semaphore rmutex = 1, wmutex = 1;
process reader { P(z); P(rmutex); P(x); read_count++; if (read_count == 1) P(wmutex); V(x); V(rmutex); V(z);
P(x); read_count--; if (read_count == 0) V(wmutex); V(x); }
process writer { P(y); write_count++; if (write_count == 1) P(rmutex); V(y);
P(wmutex); V(wmutex);
P(y); write_count--; if (write_count == 0) V(rmutex); V(y); }
|
读写公平
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| semaphore rmutex = 1; semaphore wmutex = 1; semaphore S = 1; int read_count = 0;
process reader_i() { while (true) { P(S); P(rmutex); if (read_count == 0) P(wmutex); ++read_count; V(rmutex); V(S); read(); P(rmutex); if (--read_count == 0) P(wmutex); V(rmutex); } }
process writer_i() { while (true) { P(S); P(wmutex); write(); V(wmutex); V(S); } }
|