P,V操作及同步互斥實例


無論是計算機考研、計算機軟件水平考試、計算機操作系統期末考試還是其他計算機崗位考試,P、V原語操作都是一個常考點。下面筆者總結了關於P、V操作的一些知識。

信號量是最早出現的用來解決進程同步與互斥問題的機制(也可實現進程通信),包括一個稱為信號量的變量及對它進行的兩個原語操作。信號量為一個整數,我們設這個信號量為:sem。很顯然,我們規定在sem大於等於零的時候代表可供並發進程使用的資源實體數,sem小於零的時候,表示正在等待使用臨界區的進程的個數。根據這個原則,在給信號量附初值的時候,我們顯然就要設初值大於零。

p操作和v操作是不可中斷的程序段,稱為原語。P,V原語中P是荷蘭語的Passeren,相當於英文的pass, V是荷蘭語的Verhoog,相當於英文中的incremnet。

且在P,V原語執行期間不允許有中斷的發生。

對於具體的實現,方法非常多,可以用硬件實現,也可以用軟件實現。這種信號量機制必須有公共內存,不能用於分布式操作系統,這是它最大的弱點。

首先應弄清PV操作的含義:PV操作由P操作原語和V操作原語組成(原語是不可中斷的過程),對信號量進行操作,具體定義如下:

 

             P(S):①將信號量S的值減1,即S=S-1;

                    ②如果S>=0,則該進程繼續執行;否則該進程置為等待狀態,排入等待隊列。

             V(S):①將信號量S的值加1,即S=S+1;

                    ②如果S>0,則該進程繼續執行;否則釋放隊列中第一個等待信號量的進程。

PV操作的意義:我們用信號量及PV操作來實現進程的同步和互斥。PV操作屬於進程的低級通信。

什么是信號量?信號量(semaphore)的數據結構為一個值和一個指針,指針指向等待該信號量的下一個進程。信號量的值與相應資源的使用情況有關。當它的值大於0時,表示當前可用資源的數量;當它的值小於0時,其絕對值表示等待使用該資源的進程個數。注意,信號量的值僅能由PV操作來改變。

一般來說,信號量S>=0時,S表示可用資源的數量。執行一次P操作意味着請求分配一個單位資源,因此S的值減1;

當S<0時,表示已經沒有可用資源,請求者必須等待別的進程釋放該類資源,它才能運行下去。而執行一個V操作意味着釋放一個單位資源,因此S的值加1;

若S<=0,表示有某些進程正在等待該資源,因此要喚醒一個等待狀態的進程,使之運行下去

利用信號量和PV操作實現進程互斥的一般模型是:

進程P1                   進程P2                ……               進程Pn

……                     ……                  ……

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

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

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

……                     ……                  ……               ……

其中信號量S用於互斥,初值為1

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

(1)每個程序中用戶實現互斥的P、V操作必須成對出現,先做P操作,進臨界區,后做V操作,出臨界區。若有多個分支,要認真檢查其成對性。

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

(3)互斥信號量的初值一般為1。

利用信號量和PV操作實現進程同步

PV操作是典型的同步機制之一。用一個信號量與一個消息聯系起來,當信號量的值為0時,表示期望的消息尚未產生;當信號量的值非0時,表示期望的消息已經存在。用PV操作實現進程同步時,調用P操作測試消息是否到達,調用V操作發送消息。

利用信號量和PV操作實現進程互斥的一般模型是:

進程A                            進程B

  ....                            ....

L: P(信號量)                     L2:V(信號量)

  ....                            ....

使用PV操作實現進程同步時應該注意的是:

(1)分析進程間的制約關系,確定信號量種類。在保持進程間有正確的同步關系情況下,哪個進程先執行,哪些進程后執行,彼此間通過什么資源(信號量)進行協調,從而明確要設置哪些信號量。

(2)信號量的初值與相應資源的數量有關,也與P、V操作在程序代碼中出現的位置有關。

(3)同一信號量的P、V操作要成對出現,但它們分別在不同的進程代碼中。

【例1】生產者-消費者問題

在多道程序環境下,進程同步是一個十分重要又令人感興趣的問題,而生產者-消費者問題是其中一個有代表性的進程同步問題。下面我們給出了各種情況下的生產者-消費者問題,深入地分析和透徹地理解這個例子,對於全面解決操作系統內的同步、互斥問題將有很大幫助。

(1)一個生產者,一個消費者,公用一個緩沖區。

定義兩個同步信號量:

empty——表示緩沖區是否為空,初值為1。

full——表示緩沖區中是否為滿,初值為0。

生產者進程:

while(TRUE){

      生產一個產品;

      P(empty);

      產品送往Buffer;

      V(full);
 }

消費者進程:

while(TRUE){

     P(full);

     從Buffer取出一個產品;

     V(empty);

     消費該產品;
}

 

(2)一個生產者,一個消費者,公用n個環形緩沖區。

定義兩個同步信號量:

empty——表示緩沖區是否為空,初值為n。

full——表示緩沖區中是否為滿,初值為0。

             設緩沖區的編號為1~n&61485;1,定義兩個指針in和out,分別是生產者進程和消費者進程使用的指針,指向下一個可用的緩沖區。

生產者進程:

while(TRUE){

    生產一個產品;

    P(empty);

    產品送往buffer(in);

    in=(in+1)mod n;

    V(full);
}

消費者進程:

while(TRUE){

    P(full);

    從buffer(out)中取出產品;

    out=(out+1)mod n;

    V(empty);

    消費該產品;

}

 

(3)一組生產者,一組消費者,公用n個環形緩沖區

             在這個問題中,不僅生產者與消費者之間要同步,而且各個生產者之間、各個消費者之間還必須互斥地訪問緩沖區。

定義四個信號量:

empty——表示緩沖區是否為空,初值為n。

full——表示緩沖區中是否為滿,初值為0。

mutex1——生產者之間的互斥信號量,初值為1。

mutex2——消費者之間的互斥信號量,初值為1。

             設緩沖區的編號為1~n&61485;1,定義兩個指針in和out,分別是生產者進程和消費者進程使用的指針,指向下一個可用的緩沖區。

生產者進程:

while(TRUE){

    生產一個產品;

    P(empty);

    P(mutex1);

    產品送往buffer(in);

    in=(in+1)mod n;

    V(mutex1);

    V(full);

}

消費者進程:

while(TRUE){

    P(full);

    P(mutex2);

    從buffer(out)中取出產品;

    out=(out+1)mod n;

    V(mutex2);

    V(empty);

    消費該產品;

}

需要注意的是無論在生產者進程中還是在消費者進程中,兩個P操作的次序不能顛倒。應先執行同步信號量的P操作,然后再執行互斥信號量的P操作,否則可能造成進程死鎖。

 

【例2】桌上有一空盤,允許存放一只水果。爸爸可向盤中放蘋果,也可向盤中放桔子,兒子專等吃盤中的桔子,女兒專等吃盤中的蘋果。規定當盤空時一次只能放一只水果供吃者取用,請用P、V原語實現爸爸、兒子、女兒三個並發進程的同步。

分析在本題中,爸爸、兒子、女兒共用一個盤子,盤中一次只能放一個水果。當盤子為空時,爸爸可將一個水果放入果盤中。若放入果盤中的是桔子,則允許兒子吃,女兒必須等待;若放入果盤中的是蘋果,則允許女兒吃,兒子必須等待。本題實際上是生產者-消費者問題的一種變形。這里,生產者放入緩沖區的產品有兩類,消費者也有兩類,每類消費者只消費其中固定的一類產品。

             解:在本題中,應設置三個信號量S、So、Sa,信號量S表示盤子是否為空,其初值為l;信號量So表示盤中是否有桔子,其初值為0;信號量Sa表示盤中是否有蘋果,其初值為0。同步描述如下:

int S=1;
int Sa=0;
int So=0;
main()
{
     cobegin
     father();              
     son();                
     daughter();            
     coend
}
father()
{
     while(1)
   {
       P(S);
          將水果放入盤中;
      if(放入的是桔子)
              V(So);
          else 
              V(Sa);
     }
}
son()
{
    while(1)
    {
        P(So);
        從盤中取出桔子;
        V(S);
        吃桔子;
     }
}
daughter()
{
    while(1)
    {
        P(Sa);
        從盤中取出蘋果;
        V(S);
        吃蘋果;
     }
}                        

 

例題3 設公交車上,司機和售票員的活動如下:司機;啟動車輛;正常行使,到站停車. 售票員;關車門,售票 開車門. 在汽車不斷到站 停車行駛過程中這兩個活動有什么同步關系? 用信號量和pv操作實現。

設信號量為s1(是否開車)和s2(是否停車),s1=1,s2=0;

司機進程:                      售票員進程:
begin                           begin
L1:                             L2:
P(S1);                          關閉車門;
啟動車輛;                      V(s1);  
正常行駛;                      售票;
V(s2);                        P(s2);
goto L1;                        開車門;
end;                           goto L2;
                                end;

  

思考題:

四個進程A、B、C、D都要讀一個共享文件F,系統允許多個進程同時讀文件F。但限制是進程A和進程C不能同時讀文件F,進程B和進程D也不能同時讀文件F。為了使這四個進程並發執行時能按系統要求使用文件,現用PV操作進行管理,請回答下面的問題:

(1)應定義的信號量及初值:                             。

(2)在下列的程序中填上適當的P、V操作,以保證它們能正確並發工作:

   A()             B()            C()                D()
  {              {               {                  {
    [1];            [3];           [5];               [7];
    read F;         read F;        read F;            read F;
    [2];            [4];         [6];                 [8];
  }              }              }                   }

  

思考題解答:

(1)定義二個信號量S1、S2,初值均為1,即:S1=1,S2=1。其中進程A和C使用信號量S1,進程B和D使用信號量S2。

(2)從[1]到[8]分別為:P(S1) V(S1) P(S2) V(S2) P(S1) V(S1) P(S2) V(S2)

信號量、PV操作是解決進程間的同步與互斥問題的。

★     做題時尤其要注意隱藏的同步、互斥問題。這些問題通常可以歸入生產者-消費者問題和閱讀者-寫入者問題。

★     PV操作一定是成對出現的,但是這不意味着它會在一個進程內成對出現。

★     在互斥關系中,PV操作一定是在一個進程內成對出現。而且,信號一定大於0,具體多少視情況而定。而對於同步關系,則一對PV操作在兩個進程或者更多的進程中出現。

★     對於同步關系,信號量可能為0,也可能不為0;用於同步的信號個數可能1個,也可能是多個。

★     對信號量為1的,應該先執行V操作。

★     在生產者-消費者問題中,要設置三個信號量:empty-空閑的緩存區數量,初值為n;full-已填充的緩存區數量,初值為0;mutex-保證只有一個進程在寫入緩存區,初值為1。

 ★     在閱讀者-寫入者問題中,設置兩個信號量:信號量access-控制寫入互斥,初值為1;信號量rc-控制對共享變量ReadCount(讀者統計值)的互斥訪問。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM