PV操作系列--讀者寫者問題

問題描述

有一個許多進程共享的數據區,這個數據區可以是一個文件或者主存的一塊空間;有一些只讀取這個數據區的進程(Reader)和一些只往數據區寫數據的進程(Writer),此外還需要滿足以下條件:
(1) 任意多個讀進程可以同時讀這個文件;
(2) 一次只有一個寫進程可以往文件中寫;
(3) 如果一個寫進程正在進行操作,禁止任何讀進程度文件。

讀優先

一個讀者試圖進行讀操作時,如果這時正有其他讀者在進行操作,他可直接開始讀操作,而不需要等待。

readcount  //讀者計數器
var rwmutex, rmutex = 1, 1int readcount = 0; 
cobegin 
	procedure reader_i            procedure Writer_j  // i,j = 1,2,….
	while true then               while true then
	begin                         begin
	P(rmutex);                    P(rwmutex); 
	                              寫更新;
	Readcount + +;                V(rwmutex); 
	if (readcount = = 1)          end
		P(rwmutex);
	V(rmutex);
	讀數據; 
	P(rmutex); 
	Readcount - -;
	if (readcount = = 0) 
		V(rwmutex);
	V(rmutex);
end
Coend

讀優先–代碼分析

讀進程

  • readcount 表示讀進程數
  • rmutex 是對於計數器readcount操作的互斥信號量,rwmutex表示是否允許寫的信號量
  • P(rmutex) 表示對每次有一個讀者要進行讀操作,要先對readcount 共享變量互斥操作,然後判斷當前是否是第一名讀者,如果是第一名讀者,那麼接下來將判斷rwmutex信號量得出此時是否有作者在臨界區(有的話,阻塞讀進程;無,阻塞寫進程)
  • V(rmutex)表示結束對readcount共享信號量的互斥訪問
  • 讀者讀完後,又開始對readcount共享信號量的互斥訪問,此時需要判斷readcount是否爲0,代表最後一個人離開讀進程區,從而判斷是否有寫進程,if yes,喚醒其中一個寫進程到臨界區

寫進程

  • 確保沒有讀進程情況下,寫進程才能不阻塞
  • 寫進程完畢,判斷是否有阻塞的讀進程,if yes,喚醒其中一個讀進程進入臨界區

寫優先

一個讀者試圖進行讀操作時,如果有其他寫者在等待進行寫操作或正在進行寫操作,他要等待該寫者完成寫操作後纔開始讀操作。

1)多個讀者可以同時進行讀
2)寫者必須互斥(只允許一個寫者寫,也不能讀者寫者同時進行)
3)寫者優先於讀者(一旦有寫者,則後續讀者必須等待,喚醒時 優先考慮寫者),假設讀者數是固定的
對第三點的解析:讀寫互斥,P原語,V原語操作首先考慮寫者
我們可採用下面的算法:

rwmutex:用於寫者與其他讀者/寫者互斥的訪問共享數據
rmutex:該信號量初始值設爲10,表示最多允許10個讀者進程同時進行讀操作
var rwmutex, rmutex: semaphore := 1, 10;

cobegin 
procedure reader_i          procedure Writer_j
begin	                    begin // j = 1,2,….
P(rwmutex);                 P(rwmutex);
P(rmutex);                  for (i = 1;i <= 10;i + +) P(rmutex);
V(rwmutex);                 //禁止新讀者,並等待已進入的讀者退出讀進程
							// 寫更新;
V(rmutex);                  for (i = 1;i <= 10;i + +) V(rmutex);
end                         //恢復允許rmutex值爲10,喚醒讀進程
                            v(rwmutex)
							end

Coend 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章