5.P、V操做和消費者問題

用信號量實現互斥併發

Var mutex:semaphoer:=1;
	Begin
		Parbegin
		Process1:begin		//第一個進程
				repeat
					wait(mutex);
					critical section
					signal(mutex);
					remainder section
				until false;
					end;
		Process2:begin		//第二個進程
			repeat
				wait(mutex);		//申請資源
				critical section	//使用臨界區
				singal(mutex);	//釋放資源
				remainder section	//剩餘區代碼
			until false;
			end
	Parend

注意

  • 在實現互斥時,wait(mutex)和singal(mutex)必須成對地出現
  • 缺wait(mutex)將會引發系統混亂,不能保證對臨界資源的互斥訪問
  • 缺singal(mutex)將會使該臨界資源永久不會被釋放

經典的同步問題

  • 生產者——消費者問題
  • 讀者——寫者問題
  • 哲學家進餐問題

生產者——消費者問題

一組生產者進程生產產品給一組消費者進程消費。爲使他們併發執行,設一個有n個緩衝區的緩衝池,生產者一次向一個緩衝區中投入消息,消費者從一個緩衝區中取得消息。生產者——消費者問題其實是相互合做進程關係的一種抽象。code

例子

  • 在輸入時,輸入進程是生產者,計算進程是消費者
  • 在輸出時,計算進程是生產者,打印進程是消費者

制約關係

  • 不容許消費者進程到一個空緩衝區中取產品
  • 不容許生產者進程到一個已滿且還沒被取走的緩衝區中投放產品

用記錄型信號量解決生產者——消費者問題

  • 設有n個緩衝區,每一個緩衝區存放一個消息,用互斥信號量mutex對緩衝池實現互斥訪問
  • 利用資源信號量empty和full分別表示緩衝池中空緩衝區及滿緩衝區的數量,又假定這些生產者和消費者相互等效,只要緩衝池未滿,生產者即可將消息送入緩衝池;只要緩衝池未空,消費者即可從緩衝池取走一個消息。
var mutex:semaphore:=1;
	empty:semaphore:=n;
	full:semaphore:=0;
	
buffer:array[0,1,……,n-1] of item;	//生產者生產出來的一個數據就是item
	in,out:integer:=0,0;	//in記錄放入數據的地址,out記錄取出數據的地址,其實就是buffer下標

生產者進程:進程

Procedure:begin
	repeat
		……
	procedure an item nextp;  //生產一個數據(下一個)
		……
		wait(empty);	//申請一個空緩衝區,申請成功,empty信號量減1
		wait(mutex);
		Buffer(in):=nextp;	  //將nextp放入下標是in的緩衝區中
		in:=(in+1) mod n;
		singal(mutex);			//釋放緩衝區
		singal(full);			//將full信號量加1
		until false;
		end;

消費者進程資源

consumer:begin
		repeat
			wait(full);		//申請一個緩衝區
			wait(mutex);	//含義是判斷當前有沒有生產者在使用申請的緩衝區
			nextc:=Buffer(out);
			out:=(out+1) mod n;
			singal(mutex);
			singal(empty);		//釋放一個空緩衝區,empty加1
		Consumer the item in nextc;
		until false;
		end;

注意

  • 每一個程序中互斥的wait(mutex)和singal(mutex)必須成對出現。
  • 對資源信號量empty和full的P、V操做成對出現,但它們分別處於不一樣的程序中。例如P在計算進程中,而V在打印進程中,計算進程若因執行P而阻塞,則之後將由打印進程將它喚醒。
  • 每一個程序中的P操做順序不能顛倒。應先執行對資源信號量的P操做,而後再執行對互斥信號量的P操做,不然可能引發進程死鎖。
  • V操做的順序無所謂,均可以。
相關文章
相關標籤/搜索