P操作和V操作是不可中斷的程序段,稱為原語,PV原語及信號量的概念都是由荷蘭科學家E.W.Dijkstra提出的。
信號量sem是一個整數,Sem大於等於零時代表可供並發進程使用的資源實體數,sem小於零時則表示正在等待申請資源的進程數。
P原語操作
(1) sem減 1 ;
(2) 若sem大於等於0,則請求的進程繼續執行;
(3) 若sem小於0,則進程被阻塞后進入與該信號相對應的等待隊列中,然后轉進程調度。
V原語操作
(1) sem加 1 ;
(2) 若sem大於0,則請求的進程繼續執行;
(3) 若sem小於等於0,則從該信號的等待隊列中喚醒一個等待進程,然后再返回原進程繼續執行或轉進程調度。
注意事項:
⑴每個程序中用戶實現互斥的P、V操作必須成對出現,先做P操作,進臨界區,后做V操作,出臨界區。若有多個分支,要認真檢查其成對性。
⑵P、V操作應分別緊靠臨界區的頭尾部,臨界區的代碼應盡可能短,不能有死循環。
⑶互斥信號量的初值一般為1。
典型問題:
1、V操作中 ,Sem大於0那就表示有可供使用,為什么不喚醒進程?
==》Sem大於0的確表示有臨界資源可供使用,而且這個時候沒有進程被阻塞在這個資源上,也就是說沒有進程因為得不到這類資源而阻塞,所以沒有被阻塞的進程,自然不需要喚醒。
2、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,表明有進程阻塞在該類資源上,於是喚醒一個。
3、Sem的絕對值表示等待的進程數,同時又表示臨界資源,這到底是怎么回事?
==》當信號量Sem小於0時,其絕對值表示因請求該類資源而被阻塞的進程數目。S大於0時表示可用的臨界資源數。注意在不同情況下所表達的含義不一樣。當S等於0時,表示臨界資源剛好用完。
4、如果是互斥的話,應該設置信號量Sem=1,但是當有5個進程都訪問的話,最后在該信號量的鏈表里會有4個在等待,也是說S=-4,那么第一個進程執行了V操作使S加1,釋放了資源,下一個應該能夠執行,但喚醒的這個進程在執行P操作時因S<0,也還是執行不了,這是怎么回事呢?
==》當一個進程阻塞了的時候,它已經執行過了P操作,並卡在那個地方。當喚醒它時就立即進入它自己的臨界區,並不需要執行P操作了,當執行完了臨界區的程序后,就執行V操作。