操作系統進程管理-同步和互斥
在看了操作系統關於進程管理中的同步互斥機制章節之後,甚是困惑,今天通過視頻、網上博客資料學習之後,整理一下相關知識點。
進程管理
一、進程互斥
由於進程具有獨立性和異步性等併發特徵,計算機的資源有限,導致了進程之間的資源競爭和共享,也導致了對進程執行過程的制約。
1.臨界區相關概念:
臨界資源:也就是一次只允許一個進程操作使用的計算機資源,這裏的資源可以是物理資源,也可以是你邏輯上的變量等。
臨界區:把不允許多個併發進程交叉執行的一段程序稱爲臨界區(critical region)或臨界部分(critical section)。
當一個進程使用該臨界資源時,其他需要訪問該資源的進程必須阻塞,直到佔用者釋放該資源。
2、間接制約
把這種由於共享某一公有資源而引起的在臨界區內不允許併發進程交叉執行的現象,稱爲由共享公有資源而造成的對併發進程執行速度的間接制約。這裏的“間接”二字主要是指各併發進程的速度受公有資源的制約,而非進程之間的直接制約。
3.進程互斥
在併發進程中,一個或多個進程要對公用資源進行訪問時,必須確保該資源處於空閒狀態,也就是說,在併發進程中,臨界區只允許一個進程進入,而其他進程阻塞,等待該共享臨界資源釋放。
4.併發進程之間必須滿足一下特徵:
- 平等競爭:即各併發進程享有平等地、獨立地競爭共有資源的權利,且在不採取任何措施的條件下,在臨界區內任意指令結束時,其他併發進程可以進入臨界區。
- 互斥使用:當併發進程中的 多個進程同時申請進入臨界區時,它只允許一個進程進入臨界區。
- 不可獨佔:當進程不在臨界區後,它不能阻止其他進程進入臨界區。
- 有限等待:也就是在就緒隊列中的進程等待資源時間必須是有限的。併發進程中的某個進程從申請進入臨界區時開始,應在有限時間內得以進入臨界區。
二、互斥的實現
2.1、互斥的加鎖實現:
對互斥的臨界區進行加鎖處理,即當一個進程進入了 臨界區之後,對此臨界區進行加鎖,直到該進程退出臨界區爲止。而其他併發進程在申請進入臨界區之前,必須測試該臨界區是否加鎖,如果是,則阻塞等待!
加鎖實現是系統的原語:lock(key[S])和Unlock(key([S]))均保持原子操作。系統實現時鎖定位key[S]總是設置在公有資源所對應的數據結構中的。
2.2、互斥加鎖實現的缺點:
1.在進行鎖測試和定位中將耗費CPU資源
2、進程加鎖實現可能對進程不公平,例如:
進程A:
lock(key[S])
<S>
unlock(key[S])
Goto A
進程B:
lock(key[S])
<S>
unlock(key[S])
Goto B
如上面所示,進程A和B之間的一個進程運行到Goto之後,會使得另一個進程無法得到處理機資源運行。而處於永久飢餓狀態(starvation)。
分析可以知道,一個進程能否進入臨界區取決於進程自己調用lock過程去測試相應的鎖定位。也就是說,每個進程能否進入臨界區是依靠進程自己的測試判斷。這樣,沒有獲得執行機會的進程當然無法判斷,從而出現不公平現象。
那麼是否有辦法解決這個問題呢?當然,很明顯,辦法是有的,我們可以爲臨界區設置一個管理員,由這個管理員來管理相應臨界區的公有資源,它代表可用資源的實體,這個管理員就是信號量。
3、信號量和P、V操作
信號量和P、V原語是荷蘭科學家E. W. Dijkstra提出來的。
P原語:*P是荷蘭語Proberen(測試*)的首字母。爲阻塞原語,負責把當前進程由運行狀態轉換爲阻塞狀態,直到另外一個進程喚醒它。操作爲:申請一個空閒資源(把信號量減1),若成功,則退出;若失敗,則該進程被阻塞;
V原語:V是荷蘭語Verhogen(增加)的首字母。爲喚醒原語,負責把一個被阻塞的進程喚醒,它有一個參數表,存放着等待被喚醒的進程信息。操作爲:釋放一個被佔用的資源(把信號量加1),如果發現有被阻塞的進程,則選擇一個喚醒之。
【信號量semaphore】 在操作系統中,信號量sem是一個整數。
- sem >= 0時,代表可供併發進程使用的資源實體數;
- sem < 0時,表示正在等待使用臨界區的進程數。
顯然,用於互斥的信號量sem的初值應該大於0,而建立一個信號量必須說明所建信號量代表的意義,賦初值,以及建立相應的數據結構,以便指向那些等待使用該臨界區的進程。sem初值爲1。
【P、V原語】
信號量的數值僅能由P、V原語操作改變。採用P、V原語,可以把類名爲S的臨界區描述爲:When S do P(sem) 臨界區 V(sem) od。
- 一次P原語操作使信號量sem減1
- 一次V原語操作使信號量sem加1
P原語操作:
sem減1;
若sem減1後仍大於或等於0,則P原語返回,該進程繼續執行;
若sem減1後小於0,則該進程被阻塞後進入與該信號相對應的隊列中,然後轉進程調度。
V原語操作:
sem加1;
若相加結果大於0,V原語停止執行,該進程返回調用處,繼續執行;
若相加結果小於或等於0,則從該信號的等待隊列中喚醒一個等待進程,然後再返回原進程繼續執行或轉進程調度。
這裏給出一個使用加鎖法的軟件實現方法來實現P、V原語:
P(sem):
begin
封鎖中斷;
lock(lockbit)
val[sem]=val[sem]-1
if val[sem]<0
保護當前進程CPU現場
當前進程狀態置爲“等待”
將當前進程插入信號sem等待隊列
轉進程調度
fi
unlock(lockbit);開放中斷
end
V(sem):
begin
封鎖中斷;
lock(lockbit)
val[sem]=val[sem]+1
if val[sem]<=0
local k
從sem等待隊列中選取一個等待進程,將其指針置入k中
將k插入就緒隊列
進程狀態置位“就緒”
fi
unlock(lockbit);開放中斷
end
2.3用P、V原語實現進程互斥
設信號量sem是用於互斥的信號量,且其初始值爲1表示沒有併發進程使用該臨界區。顯然,由前面論述可知,只要把臨界區置於P(sem)和V(sem)之間,即可實現進程之間的互斥。
用信號量實現兩個併發進程PA和PB互斥的描述如下:
(1)設sem爲互斥信號量,其取值範圍爲(1,0,-1)。其中sem=1表示進程PA和PB都未進入類名爲S的臨界區,sem=0表示進程PA或PB已進入類名爲S的臨界區,sem=-1表示進程PA和PB中,一個進程已進入臨界區,而另一個進程等待進入該臨界區。
(2)實現過程:
Pa:
P(sem)
<S>
V(sem)
.
.
.
Pb:
P(sem)
<S>
V(sem)
.
.
.
三、進程同步
【進程間的直接制約】:一組在異步環境下的併發進程,各自的執行結果互爲對方的執行條件,從而限制各進程的執行速度的過程稱爲併發進程間的直接制約。這裏的異步環境主要是指各併發進程的執行起始時間的隨機性和執行速度的獨立性。
【進程間的同步】:把異步環境下的一組併發進程因直接制約而互相發送消息而進行互相合作、互相等待,使得各進程按一定的速度執行的過程稱爲進程間的同步。具有同步關係的一組併發進程稱爲合作進程,合作進程間相互發送的信號稱爲消息或事件。
用消息實現進程同步:
用
wait(消息名)
表示進程等待合作進程發來的消息。
用
signal(消息名)
表示向合作進程發送消息。
過程wait的功能是等待到消息名爲true的進程繼續執行,而signal的功能則是向合作進程發送合作進程所需要的消息名,並將其值置爲true。
【進程互斥和進程同步】:
進程同步不同於進程互斥,進程互斥時它們的執行順序可以是任意的。一般來說,也可以把個進程之間發送的消息作爲信號量看待。與進程互斥時不同的是,這裏的信號量只與制約進程及被制約進程有關,而不是與整租併發進程有關。因此,稱該信號量爲私用信號量(private semaphore)。一個進程Pi的私用信號量semi是從制約進程發送來的進程Pi的執行條件所需要的信息。與私用信號量相對應,稱互斥時使用的信號量爲公用信號量。
【用P、V原語實現進程同步】:
首先爲各併發進程設置私用信號量,然後爲私用信號量賦初值,最後利用P、V原語和私用信號量規定各進程的執行順序。