一、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時,表示剛好用完。