天天看點

java pv原語_PV操作原理概述

一、PV原語的含義

P操作和V操作是不可終端的程式段,成為原語,PV原語及信号量的概念都是由荷蘭科學家E.W.Dijkstra提出的。信号量sem是一個整數。Sem大于等于零時代表可供并發程序使用的資源實體數,但sem小于零時則表示正在等待使用臨街區的程序數。

原語操作舉例如下,P操作與V操作不允許中斷:

procedure p(var s:samephore);

{

s.value=s.value-1;

if (s.value<0) asleep(s.queue);

}

procedure v(var s:samephore);

{

s.value=s.value+1;

if (s.value<=0) wakeup(s.queue);

}

二、P原語操作的動作是:

(p可了解為pass,獲得一個資源)

(1)sem減 1 ;

(2)若sem減 1 後仍大于等于零,則請求的程序繼續執行;

(3)若sem減 1 後小于零,則程序被阻塞後進入與該信号相對應的隊列中,然後轉程序排程。

圖 P操作流程

V原語操作的動作是:

(V可了解為Release,釋放一個資源)

(1)sem加 1 ;

(2)若相加結果大于零,則請求的程序繼續執行;

(3)若相加結果小于等于零,則從該信号的等待隊列中喚醒一個等待程序,然後再傳回原程序繼續執行或轉程序排程。

PV操作對于每一個程序來說,都隻能進行一次,而且必須成對使用,在PV原語執行期間不允許有中斷的發生。

圖 V操作流程

三、利用信号量和PV操作實作的一般模型是:

程序P1 程序P2 …… 程序Pn

…… …… ……

P(S); P(S); P(S);

臨界區; 臨界區; 臨界區;

V(S); V(S); V(S);

…… …… …… ……

其中信号量S用于互斥,初值為1。

使用PV操作實作程序互斥時應該注意的是:

⑴每個程式中使用者實作互斥的P、V操作必須成對出現,先做P操作,進臨界區,後做V操作,出臨界區。若有多個分支,要認真檢查其成對性。

⑵P、V操作應分别緊靠臨界區的頭尾部,臨界區的代碼應盡可能短,不能有死循環。

⑶互斥信号量的初值一般為1。

現在,簡單的說一下“信号燈”機制,打一個跟廁所有關的比喻,(不是很雅^_^),在火車上,當A上廁所的時候,他會将廁所的門鎖上,對外辨別一個“有人”的表示,當他解決完以後,他會打開門,“有人”的辨別就會變成“無人”的辨別,這樣B就可以進去了,而如果A不把這個辨別改變,B就算憋死也進不去的。(當然暴力方式排除在外)。C# 提供的 AutoResetEvent就是這樣一種“信号燈”,定義這個類的變量,并傳遞到子線程,在子線程将結束時,将該“信号燈”設定為 true(“無人”)狀态,這樣主線程就可以進入了(開始執行)。

同樣,我們還有上公共廁所的經曆,在公共廁所了有很多個便池,當然還有一個廁所管理者,這時,A1,A2,A3……就可以在廁所管理者這裡領取一個牌匾,同時進去解決“問題”, 如果,廁所管理者不是很bt,當A1出來的時候,他會放B1進去,但是也有Bt的,非得等到A1,A2,A3……都解決問題了,才讓B1,B2,……進去,這就是WaitHandle.WaitAll()和WaitHandle.WaitAny(),WaitHandle.WaitOne()的差別,這是可以使用的“信号燈”

典型了解偏差三個問題:

一,以V的1、2步來做,Sem不就永遠大于0,那不就一直循環執行成為死循環了?

二,Sem大于0那就表示有可供使用,為什麼不喚醒程序?

三,Sem小于0應該是說沒有臨界資源可供使用,為什麼還要喚醒程序?

析疑:

一,P操作對sem減1的。P、V原語必須成對使用!進而不會造成死循環。

二,Sem大于0的确表示有臨界資源可供使用,而且這個時候沒有程序被阻塞在這個資源上,也就是說沒有程序因為得不到這類資源而阻塞,是以沒有被阻塞的程序,自然不需要喚醒。

三,V原語操作的本質在于:一個程序使用完臨界資源後,釋放臨界資源,使Sem加1,以通知其它的程序,這個時候如果Sem<0,表明有程序阻塞在該類資源上,是以要從阻塞裡喚醒一個程序來“轉手”該類資源。比如,有兩個某類資源,四個程序A、B、C、D要用該類資源,最開始Sem=2,當A進入,Sem=1,當B進入Sem=0,表明該類資源剛好用完, 當C進入時Sem=-1,表明有一個程序被阻塞了,D進入,Sem=-2。當A用完該類資源時,進行V操作,Sem=-1,釋放該類資源,而這時Sem<0,表明有程序阻塞在該類資源上,于是喚醒一個。

為了進一步加深了解,再引入二個問題:

四,如果是互斥的話,應該設定信号量Sem=1,但是當有5個程序都通路的話,最後在該信号量的連結清單裡會有4個在等待,也是說S=-4,那麼第一個程序執行了V操作使S加1,釋放了資源,下一個應該能夠執行,但喚醒的這個程序在執行P操作時因S〈0,也還是執行不了,這是怎麼回事呢?

五,Sem的絕對值表示等待的程序數,同時又表示臨界資源,這到底是怎麼回事?

析疑:

四,當一個程序阻塞了的時候,它已經執行過了P操作,并卡在那個地方。當喚醒它時就立即進入它自己的臨界區,并不需要執行P操作了,當執行完了臨界區的程式後,就執行V操作。

五,當信号量Sem小于0時,其絕對值表示中因請求該類資源而被阻塞的程序數目.S大于0時表示可用的臨界資源數。注意在不同情況下所表達的含義不一樣。當等于0時,表示剛好用完。