1. 程式人生 > >Linux基礎(四)——訊號量與PV操作

Linux基礎(四)——訊號量與PV操作

在計算機作業系統中,PV操作是程序管理中的難點。
1、基本含義
     
什麼是訊號量訊號量(semaphore)的資料結構為一個值和一個指標,指標指向等待該訊號量的下一個程序。訊號量的值與相應資源的使用情況有關。當它的值大於0時,表示當前可用資源的數量;當它的值小於0時,其絕對值表示等待使用該資源的程序個數。
     
PV操作的含義PV操作由P操作原語和V操作原語組成(原語是不可中斷的過程),對訊號量進行操作,具體定義如下:

    PS):①將訊號量S的值減1,即S=S

-1
           ②如果S>=0,則該程序繼續執行;否則該程序置為等待狀態,排入等待佇列。
    VS):①將訊號量S的值加1,即S=S+1
           ②如果S>0,則該程序繼續執行;否則釋放佇列中第一個等待訊號量的程序。
 利用訊號量和PV操作實現程序互斥的一般模型是:
    程序
P1              程序P2           ……          程序Pn
    ……
                  ……
                           ……
    P
S);              PS);                         PS);
    臨界區;             臨界區;                        臨界區;
    VS);              VS);                        VS);
    ……                  ……            ……           ……

使用PV操作實現程序互斥時應該注意的是:
    1)每個程式中使用者實現互斥的PV操作必須成對出現,先做P操作,進臨界區,後做V操作,出臨界區。若有多個分支,要認真檢查其成對性。
    2PV操作應分別緊靠臨界區的頭尾部,臨界區的程式碼應儘可能短,不能有死迴圈。
    3)互斥訊號量的初值一般為1
利用訊號量和PV操作實現程序同步:

    PV操作是典型的同步機制之一。用一個訊號量與一個訊息聯絡起來,當訊號量的值為0時,表示期望的訊息尚未產生;當訊號量的值非0時,表示期望的訊息已經存在。用PV操作實現程序同步時,呼叫P操作測試訊息是否到達,呼叫V操作傳送訊息。
    使用PV操作實現程序同步時應該注意的是:

    1)分析程序間的制約關係,確定訊號量種類。在保持程序間有正確的同步關係情況下,哪個程序先執行,哪些程序後執行,彼此間通過什麼資源(訊號量)進行協調,從而明確要設定哪些訊號量。
    2)訊號量的初值與相應資源的數量有關,也與PV操作在程式程式碼中出現的位置有關。
    3)同一訊號量的PV操作要成對出現,但它們分別在不同的程序程式碼中。
2、例子:生產者/消費者模型

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

    設緩衝區的編號為1n-1,定義兩個指標inout,分別是生產者程序和消費者程序使用的指,指向下一個可用的緩衝區。

生產者程序
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

    設緩衝區的編號為1n-1,定義兩個指標inout,分別是生產者程序和消費者程序使用的指標,指向下一個可用的緩衝區。

生產者程序
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操作,否則可能造成程序死鎖。