1. 程式人生 > >程序同步與互斥筆記

程序同步與互斥筆記

1、程序之間的兩種相互制約關係

(1)間接相互制約關係(互斥關係)

同處於一個系統中的程序,通常都共享著某種資源,如共享CPU、共享I/O裝置等,所謂間接相互制約即源於這種資源共享,使系統中本來沒有關係的程序因競爭資源產生了制約關係。

(2)直接制約關係(同步關係)

這種制約主要源於程序間的合作。比如輸入、計算、輸出。在執行過程中,某程序可能要在某些同步點上等待另一夥伴(協作程序)為它提供訊息,在未獲得訊息之前,該程序處於等待狀態,獲得資訊後被喚醒進入就緒態,才能被執行。

幾個概念:

互斥:兩個程序不能同時使用同一資源
死鎖:指多個程序互不相讓,都得不到足夠的資源
飢餓:指一個程序一直得不到資源(其他程序可能輪流佔用資源)

2、臨界資源和臨界區

程序的互斥是由於共享資源而引起的,為了描述這類情況,引入了臨界資源和臨界區的概念。

臨界資源:系統中一次只允許一個程序訪問的資源。如I/O裝置、共享檔案、共享變數等。

臨界區:併發執行的程序中,訪問臨界資源的必須互斥執行的程式碼段叫臨界區。

3、程序同步機制

(1)概念:

多個相關程序在執行次序上的協調稱為程序同步。用於保證多個程序在執行次序上的協調關係的相應機制稱為程序同步機制。

(2)程序同步機制應遵循的準則

a)空閒讓進:當臨界資源處於空閒狀態時,允許相應的程序立即進入自己的臨界區
b)忙則等待:當已有程序進入臨界區時,其他試圖進入臨界區的程序必須等待
c)有限等待:對要求進入臨界區的程序,應保證在有限時間內能進入自己的臨界區
d)讓權等待:當程序不能進入自己的臨界區時,應立即釋放處理機,以免程序陷入“忙等”狀態。

4、臨界區的互斥訪問

1.可把一個訪問臨界資源的迴圈程序描述如下:

repeat
enter section
//進入區:程序在進入臨界區之前,應先對預訪問的臨界資源進行檢查,看它是否正被訪問,如果沒有則進入臨界區對其進行訪問,並設定它為正被訪問狀態
critical section
//臨界區
exit section
退出區:將臨界區正被訪問的標誌恢復為未被訪問的標誌
remainder section
until false;

2.實現方法

a)軟體方法:比較複雜,需要較高的程式設計技巧
b)硬體指令
c)訊號量機制

5、訊號量(Semaphores)機制

1.整型訊號量

將訊號量定義為一個整形量S;S<=0表示資源已被佔用;S>0表示資源可用。訊號量S只能通過兩個標準原子操作wait(S)和signal(S)來實現,它們在執行時是不可中斷的。

wait(S):while S<=0 do;      //請求資源
S:S-1signal(S):S:S+1;        //釋放資源
進入區執行wait(S)操作,退出區執行signal(S),例如:
var s:integer;   s:=1;
parbegin
p1:begin            p2:begin
……                  ……
wait(s);                wait(s);
臨界區程式碼;          臨界區程式碼;
signal(s);          signal(s);
……                  ……
endend;
parend

2.記錄型訊號量

在整型訊號量機制中的wait操作,只要是訊號量S<=0,就會不斷地測試,因此使程序進入“忙等”狀態。記錄型訊號量機制採取了“讓權等待”的策略,這時又會出現多個程序等待訪問同一臨界資源的情況。因此除了有一個用於代表資源數目的整型變數value外,還有一個程序連結串列指標,用於連結上述所有的等待程序。
記錄型訊號量可描述為:

type semaphore=record
valueinteger;
L:list if processend

wait(S)可描述為:

procedure wait(S)                       //請求資源
var Ssemaphorebegin
S.value:=S.value-1// 相應的資源減少一個
if S.value<0 then block(S.L) ;
//小於0,該類資源已分配完畢,程序自我阻塞,放棄處理機,並插入到訊號量連結串列S.L中。此時,S.value的絕對值表示在連結串列中已阻塞程序的個數
end

signal(S)可描述為: //釋放資源

procedure signal(S)
var S: semaphore;
begin
S.value:=S.value+1;             //資源數目加一個
if S.value<=0 then wakeup(S.L);     
//仍然<=0表示在連結串列中仍有等待資源的程序被阻塞,應喚醒連結串列中的第一個等待程序
end

如果S.value的初值為1,表示只允許一個程序訪問臨界資源,此時的訊號量轉化為互斥訊號量,用於程序互斥。

3.ADD型訊號量

當某程序要先獲得多種臨界資源後才能執行時,容易處於僵持狀態(死鎖)。AND同步機制的基本思想是:將程序在整個執行中需要的所有資源,一次性全部地分配給程序,待程序使用完後再一起釋放,只要尚有一個資源未能分配給程序,其他所有可能為之分配地資源也不給它。

Swait(S1,S2,……Sn)
if  S1>=1 andand Sn>=1  then
    for i:=1 to n do 
    Si=Si-1;
    endfor
else
    自我阻塞,插到第一個Si<1的佇列Si.L,並將程式計數定位到Swait操作的起點
endif

Ssignal(S1,S2,……Sn)
if  S1>=1 andand Sn>=1  then
    for i:=1 to n do 
    Si=Si+1;
    endfor

4.訊號量集

集,說明是不止一個,前面講的記錄型訊號量機制中,wait(S)或signal(S)操作僅能對訊號量加一或者減一,即每次只能獲得或者釋放一個資源,而當一次需要N個資源時,便要進行N次wait(S)操作,顯然很低效;還有一種情況是,當資源低於某一下限值時不予分配,這樣每次分配前都需要測試該資源的數量。
當一次需要申請n種資源且資源Si申請di個資源,該類資源的可用數目低於某下限值ti時不予分配,這樣就需要對ADD訊號機制進行擴充,形成訊號量集機制。

Swait(S1,t2,d1,……Sn,tn,dn)
if  S1>=t1 andand Sn>=tn  then
    for i:=1 to n do 
    Si=Si-di;
    endfor
else
    自我阻塞,插到第一個Si<ti的佇列Si.L,並將程式計數定位到Swait操作的起點
endif

Ssignal類似。
訊號量集的特殊情況:

a)AND訊號量是所有ti、di都等於1的特例
b)Swait(S,d,d)一個訊號量,每次申請d個,低於d個不分配
c)Swait(S,1,1)退化為一般記錄型訊號量,但操作有差別
d)Swait(S,1,0)特殊訊號量,當S>=1時,允許多個程序進入特定區;當S變位0後,將阻止任何程序進入特定區,相當於一個開關。

整型和一般記錄型訊號量是先減再分配,ADD和訊號量集是先判斷後減。

6、訊號量機制的作用

1)使用訊號量實現程序間的互斥

為臨界資源設定一個互斥訊號S,並設其初值為1,在每個程序中將臨界區程式碼置於wait(S)和aignal(S)原語之間。

2)使用訊號量實現程序間的同步

前趨關係:併發執行的程序P1和P2中,分別有程式碼C1和C2,要求C1在C2開始前完成。
為每個前趨關係設定一個互斥訊號量S,其初值為0。

3)利用訊號量實現前趨關係

當程序P1中有語句S1,程序P2中有語句S2兩個併發執行希望S1執行後再執行S2,要實現這種前趨關係只需共享一個共用訊號量S並賦初值0,將signal(S)放在語句S1後,而在S2之前插入wait(S)。

7、wait-signal操作討論

1)訊號量的物理含義

S>0:表示有S個資源可用
S=0:表示無資源可用
S<0:絕對值表示等待佇列或連結串列中的程序個數
訊號量的初值應大於等於0
wait(S):申請一個資源
signal(S):時放一個資源

2)wait-signal操作必須成對出現

互斥操作時,它們同處一程序
同步操作時,不在同一程序出現

3)wait-signal操作的優缺點

優點:簡單而且表達能力強,可解決任何同步互斥問題
缺點:不夠安全;使用不當會出現死鎖;遇到複雜同步互斥問題時實現複雜