前言
讀者-寫者問題是操作系統中P、V操作部分經典的同步問題
讀者、寫者問題
1. 問題描述
讀者與寫者問題(reader-writer problem) (Courtois, 1971)也是一個經典的並發程序設計問題。有兩組並發進程:讀者和寫者,共享一個文件F,要求:
- 允許多個讀者可同時對文件執行讀操作
- 只允許一個寫者往文件中寫信息
- 任一寫者在完成寫操作之前不允許其他讀者或寫者工作
- 寫者執行寫操作前,應讓已有的寫者和讀者全部退出
2.問題分析
讀者和寫者是互斥的,寫者和寫者也是互斥的,而讀者和讀者不存在互斥問題。兩個進程,即讀者和寫者。寫者比較簡單,它和任何進程互斥,用互斥信號量的P、V操作即可解決。讀者問題比較復雜,它必須實現與寫者進程互斥的同時還要與其他讀者進程同步,因此,僅僅簡單的一對P、V操作是無法解決的。那么在這里用到了一個計算器,用它來判斷當前是否有讀者讀文件。同時這里不同讀者對計數器的訪問也應該是互斥的。
3. 讀者優先的P、V操作
semaphore rmutex = 1; // 讀進程互斥信號量
semaphore wmutex = 1; // 寫進程互斥信號量
int readcount = 0; // 讀進程計數
cobegin
process reader_i() { // 讀進程
while(true) {
P(rmutex);
readcount++;
if(readcount == 1)
P(wmutex);
V(rmutex);
{讀文件};
P(rmutex);
readcount--;
if(readcount == 0)
V(wmutex);
V(rmutex);
}
}
process writer_i() { // 寫進程
while(true) {
P(wmutex);
{寫文件};
V(wmutex);
}
}
coend
說明:此P、V操作是讀進程優先,當一個讀進程占用了臨界資源后,后續的讀進程便能陸續的進入臨界區,而寫進程只能被迫等待。增加互斥信號量S可解決讀進程優先問題!
4. 公平競爭的讀寫P、V操作
semaphore rmutex = 1; // 讀進程互斥信號量
semaphore wmutex = 1; // 寫進程互斥信號量
int readcount = 0; // 讀進程計數
semaphore S = 1; // 保證readcount++能完整執行的互斥信號量
cobegin
process reader_i() { // 讀進程
while(true) {
P(S);
P(rmutex);
readcount++;
if(readcount == 1)
P(wmutex);
V(rmutex);
V(S);
{讀文件};
P(rmutex);
readcount--;
if(readcount == 0)
V(wmutex);
V(rmutex);
}
}
process writer_i() { // 寫進程
while(true) {
P(S);
P(wmutex);
{寫文件};
V(wmutex);
V(S);
}
}
coend
