pv操作實現多進程同步和互斥

       本篇文章,講解了PV操作的作用,舉了兩個情景模擬pv操作的應用原理,同時講解了PV操作涉及到的基本概念,並且在文章的最後用僞代碼寫了pv操作過程。

 

       要理解PV操作,請先看兩個場景:

 

場景1:飛機場售票窗口進程

Process Pi(i=1,2,3,…,n)

Begin

	查找當天機票剩餘量A

	If A>1 then

		A=A-1;

		售出一張票

	Else 輸出票以售完

End

 

       若同時有5個窗口執行該程序,如果5個程序同時併發執行,同時取到相同的票數(實際情況中:用鎖就能解決該問題,不會取到相同的票數,此處只是爲說明pv操作),則售了5張票,而實際票數只減了1張。

 

       場景2:進程A向緩存中寫數據(緩存只存一條數據),進程B從緩存存數據。如果在B未取走數據前就寫入數據,數據會被覆蓋;若A還沒寫入新數據前B寫入一次數據,則會讀取到舊數據,怎麼保證兩個進程能夠同步執行?

 

        情景一爲互斥問題,當一個進程讀取並修改數據的時候,另一個進程不能讀取數據;情景二爲同步問題,只有在進程A寫入數據後,B才能讀數據,否則可能讀到空數據或者重複數據;B讀取完,A才能寫入數據,否則可能數據還沒有讀的時候就被覆蓋掉。

 

使用PV操作可以解決上面的兩個問題,pv操作通過觀察信號量,從而控制多個進程間同步或互斥使用資源。

理解PV操作需要理解幾個重要的概念:臨界區,P操作,V操作,同步和互斥。

 

進程的互斥:若干個進程都要訪問某一共享資源時,任何時刻最多隻允許一個進程使用該資源,其他要使用該資源的進程必須等待,知道該資源的佔用者釋放進程。

進程的同步:併發進程間存在一種制約關係,一個進程的執行依賴另一個進程的消息,當一個進程沒有得到另一個進程的消息時等待,知道消息到達才被喚醒。

 

臨界區:當N個進程都要訪問同一個變量時,我們把與共享變量有關的程序段成爲臨界區。所有涉及該變量的臨界區成爲相關臨界區。

信號量:表示臨界區的進程是否可以往下執行,用S signal 代表信號量 ,s>0,代表當前變量或資源可以使用,該進程可以執行;S=0,表示當前無資源,當前進程不可往下執行;s<0表示當前有等待使用資源的進程,並且該負數的絕對值代表等待資源的進程數

p操作:判斷調用P操作的進程是否可以獲得資源並往下執行,如果信號量減一後大於0,將會往下執行,否則繼承進入等待隊列;

用代碼表示:

Procedure P(Var S:Semaphore);

Begin

	s=s-1;

	If s<0 then W(s);

End;{P}

 

V操作:進程釋放一個變量或資源,信號量加一,若等待隊列有進程,則釋放一個等待進程(該進程獲取資源並執行)

Procedure V(Var S:Semaphore);

Begin

	s=s+1

	if S<=0 then r(s)

end


 

那麼瞭解了PV操作和相關的概念後,我們可以試着用PV操作解決文章開始的兩個場景了:

解決場景一:將PV操作將如到場景一的僞代碼中

 

Begin

S:semaphore  //定義信號量

S=1;

Process Pi(i=1,2,3,…,n)

	Begin

		查找當天機票剩餘量A

		P(S);           //進行P操作,當前的信號量減1大於等於0,則繼續進行,否則等待資源

		If A>1 then

			A=A-1;

			V(S)             //將當前變量或資源釋放,將信號量加一,結果如果小於等於0,則喚醒一個進程

			售出一張票

	Else 輸出票以售完

	End

End

 

        那麼此時,由於將信號量設置爲1,只能有一個進程訪問並修改機票數量,因此不會出現問題。

       有此可見,當信號量爲正時,信號量的數值代表有幾個可用資源,爲0時,表示當前沒有可用資源,爲負值時說明當前有進程在等待資源。

 

解決場景二:

Begin

Buffer:integer

SA,SB:semaphore;

SA=1,SB=0;//定義A進程的信號量和B進程的信號量

Process A

	Begin

		L1:  向緩存中寫入一個數據Data;

		P(SA);         //進行P操作,判斷當前進程A是否可以向緩存寫入數據

		Buffer=Data;

		V(SB);              //A進程寫入說後,將B進程的信號量加一,告訴B進程可以進行讀數據了

		Goto L1;

	End ;

Process B

	Begin

		L2:     P(SB);                                         //進行P操作,判斷當前進程B是否可以從緩存讀數據

		從緩存取出一個數據Data;

		V(SA);                 //讀完數據後,將A進程的信號量加一,告訴A進程可以寫入數據了

		用取出的數據進行計算;

		Goto L2;

	End

End 


 

PV操作解決了多個進程間共享數據和資源時,誤操作的問題,保證了安全的共享資源。

 

 

 

 

 

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