簡介
1962年,狄克斯特拉離開數學中心進入位於荷蘭南部的艾恩德霍芬技術大學(Eindhoven Technical University)任數學教授。在這裡,他參加了X86計算機的開發,設計與實現了具有多道程式運行能力的作業系統——THE Multiprogramming System。
詳細資訊
THE 是艾恩德霍芬技術大學的荷蘭文Tchnische Hoogeschool Eindhov –en的詞 頭縮寫。狄克斯特拉在THE這個系統中所提 出的一系統方法和技術奠定了計算機現代作業系統的基礎,尤其是關於多層體系結構,順序進程之間的同步和互斥機制這樣一些重要的思想和概念都是狄克斯特拉在THE中首先提出並為以後的作業系統如UNⅨ等所採用的。
為了在單處理機的情況下確定進程(process)能否占有處理機,狄克斯特拉將每個進程分為“就緒”(ready)、“運行”(running)和“阻塞”(blocking)三個工作 狀態。由於在任一時刻最多只有一個進程可以使用處理機,正占用著處理機的進程稱為“運行”進程。當某進程已具備了使用處理機的條 件,而當前又沒有處理機供其使用,則使該進程處於“就緒”狀態。當運行進程由於某種原因無法繼續運行下去時,就停止其占用處理機,使之進入“阻塞”狀態,待造成其退出運行的條件解除,再進入“就緒”狀態。而對系統中所有同時運行的進程之間所存在的相互制約的同步(synchronization,指為了避免錯誤,在一個進程訪問共享數據時,另一個進程不訪問該數據)和互斥(mutually-exclusive,指兩個進程不能同時在一個臨界區中使用同一個可重複使用的資源,諸如讀寫緩衝區)兩個關係,狄克斯特拉巧妙地利用火車運行控制系統中的“信號燈”(semaphore,或叫“信號量”)概念加以解決。
所謂信號燈,實際上就是用來控制進程狀態的一個代表某一資源的存儲單元。例如,P1和P2是分別將數據送入緩衝B和從緩衝B讀出數據的兩個進程,為了防止這兩個進程並發時產生錯誤,狄克斯特拉設計了一種同步機制叫“PV操作”,P操作和V操作是執行時不被打斷的兩個作業系統原語。執行P操作P(S)時信號量S的值減1,若結果不為負則P(S)執行完畢,否則執行P操作的進程暫停以等待釋 放。執行V操作V(S)時,S的值加1,若結果大於0則釋放一個因執行P(S)而等待的進程。對P1和P2可定義兩 個信號量S1和S2,初 值分別為1和0。進程P1在向緩衝B送入數據前執行P操 作P(S1),在送入數據後執行V操 作V(S2)。進程P2在從緩衝B讀取數 據前先執行P操作P(S2),在讀出數據 後執行V操作V(S1)。當P 1往緩衝B送入一數據後信號量S1之值變為0,在該數據讀出後S1之值才又變為1,因此在前一數未讀出前 後一數不會送入,從而保 證了P1和P2之間的同步。
中國讀者常常不明白這一同步機制為什麼叫PV操作,原 來這是狄克斯特拉用荷蘭文定義的,因為在荷 蘭文中,通過叫passeren,釋放叫vrijgeven,PV操 作因此得名。這是在計算機術語中不是用英 語表達的極少數的例子之一。
解釋
1962年,狄克斯特拉離開數學中心進入位於荷蘭南部的艾恩德霍芬技術大學(Eindhoven Technical University)任數學教授。在這裡,他參加了X8計算機的開發,設計與實現了具有多道程式運行能力的作業系統——THE Multiprogramming System。THE是艾恩德霍芬技術大學的荷蘭文Tchnische Hoogeschool Eindhov –en的詞頭縮寫。狄克斯特拉在THE這個系統中所提出的一系統方法和技術奠定了計算機現代作業系統的基礎,尤其是關於多層體系結構,順序進程之間的同步和互斥機制這樣一些重要的思想和概念都是狄克斯特拉在THE中首先提出並為以後的作業系統如UNⅨ等所採用的。為了在單處理機的情況下確定進程(process)能否占有處理機,狄克斯特拉將每個進程分為“就緒”(ready)、“運行”(running)和“阻塞”(blocking)三個工作狀態。由於在任一時刻最多只有一個進程可以使用處理機,正占用著處理機的進程稱為“運行”進程。當某進程已具備了使用處理機的條件,而當前又沒有處理機供其使用,則使該進程處於“就緒”狀態。當運行進程由於某種原因無法繼續運行下去時,就停止其占用處理機,使之進入“阻塞”狀態,待造成其退出運行的條件解除,再進入“就緒”狀態。而對系統中所有同時運行的進程之間所存在的相互制約的同步(synchronization,指為了避免錯誤,在一個進程訪問共享數據時,另一個進程不訪問該數據)和互斥(mutually-exclusive,指兩個進程不能同時在一個臨界區中使用同一個可重複使用的資源,諸如讀寫緩衝區)兩個關係,狄克斯特拉巧妙地利用火車運行控制系統中的“信號燈”(semaphore,或叫“信號量”)概念加以解決。所謂信號燈,實際上就是用來控制進程狀態的一個代表某一資源的存儲單元。例如,P1和P2是分別將數據送入緩衝B和從緩衝B讀出數據的兩個進程,為了防止這兩個進程並發時產生錯誤,狄克斯特拉設計了一種同步機制叫“PV操作”,P操作和V操作是執行時不被打斷的兩個作業系統原語。執行P操作P(S)時信號量S的值減1,若結果大於等於0,則P(S)執行完畢,否則執行P操作的進程暫停以等待釋放。執行V操作V(S)時,S的值加1,若結果大於0,則釋放一個因執行P(S)而等待的進程。對P1和P2可定義兩個信號量S1和S2,初值分別為1和0。進程P1在向緩衝B送入數據前執行P操作P(S1),在送入數據後執行V操作V(S2)。進程P2在從緩衝B讀取數據前先執行P操作P(S2),在讀出數據後執行V操作V(S1)。當P1往緩衝B送入一數據後信號量S1之值變為0,在該數據讀出後S1之值才又變為1,因此在前一數未讀出前後一數不會送入,從而保證了P1和P2之間的同步。
信號量是最早出現的用來解決進程同步與互斥問題的機制,
包括一個稱為信號量的變數及對它進行的兩個原語操作。
信號量的概念
1.信號量的類型定義
信號量(semaphore)的數據結構為一個值和一個指針,指針指向等待該信號量的下一個進程。信號量的值與相應資源的使用情況有關。當它的值大於0時,表示當前可用資源的數量;當它的值小於0時,其絕對值表示等待使用該資源的進程個數。注意,信號量的值僅能由PV操作來改變。
一般來說,信號量S>=0時,S表示可用資源的數量。執行一次P操作意味著請求分配一個單位資源,因此S的值減1;當S<0時,表示已經沒有可用資源,請求者必須等待別的進程釋放該類資源,它才能運行下去。而執行一個V操作意味著釋放一個單位資源,因此S的值加1;若S<0,表示有某些進程正在等待該資源,因此要喚醒一個等待狀態的進程,使之運行下去。
2.PV原語
PV操作是典型的同步機制之一。用一個信號量與一個訊息聯繫起來,當信號量的值為0時,表示期望的訊息尚未產生;當信號量的值非0時,表示期望的訊息已經存在。用PV操作實現進程同步時,調用P操作測試訊息是否到達,調用V操作傳送訊息。
對一個信號量變數可以進行兩種原語操作:P操作和V操作,定義如下:
procedure P(var s:semaphore);
{
s.value=s.value-1;
if (s.value<0) asleep(s.queue);
}
procedure V(var s:semaphore);
{
s.value=s.value+1;
if (s.value<=0) wakeup(s.queue);
}
其中用到兩個標準過程:
asleep(s.queue);執行此操作的進程的PCB進入s.queue尾部,進程變成等待狀態
wakeup(s.queue);將s.queue頭進程喚醒插入就緒佇列
s.value初值為1時,可以用來實現進程的互斥。
p操作和v操作是不可中斷的程式段,稱為原語。如果將信號量看作共享變數,則pv操作為其臨界區,多個進程不能同時執行,一般用硬體方法保證。一個信號量只能置一次初值,以後只能對之進行p操作或v操作。
由此也可以看到,信號量機制必須有公共記憶體,不能用於分散式作業系統,這是它最大的弱點。
V原語的主要操作是:
⑴sem加1;
⑵若相加結果大於零,則進程繼續執行;
⑶若相加結果小於或等於零,則喚醒一阻塞在該信號量上的進程,然後再返回原進程繼續執行或轉進程調度。
利用信號量和PV操作實現進程互斥的一般模型是:
進程P1 進程P2 …… 進程Pn
…… …… ……
P(S); P(S); P(S);
臨界區; 臨界區; 臨界區;
V(S); V(S); V(S);
…… …… …… ……
其中信號量S用於互斥,初值為1。
使用PV操作實現進程互斥時應該注意的是:
⑴每個程式中用戶實現互斥的P、V操作必須成對出現,先做P操作,進臨界區,後做V操作,出臨界區。若有多個分支,要認真檢查其成對性。
⑵P、V操作應分別緊靠臨界區的頭尾部,臨界區的代碼應儘可能短,不能有死循環。
⑶互斥信號量的初值一般為1。
利用信號量和PV操作實現進程同步:
PV操作是典型的同步機制之一。用一個信號量與一個訊息聯繫起來,當信號量的值為0時,表示期望的訊息尚未產生;當信號量的值非0時,表示期望的訊息已經存在。用PV操作實現進程同步時,調用P操作測試訊息是否到達,調用V操作傳送訊息。
使用PV操作實現進程同步時應該注意的是:
⑴分析進程間的制約關係,確定信號量種類。在保持進程間有正確的同步關係情況下,哪個進程先執行,哪些進程後執行,彼此間通過什麼資源(信號量)進行協調,從而明確要設定哪些信號量。
⑵信號量的初值與相應資源的數量有關,也與P、V操作在程式代碼中出現的位置有關。
⑶同一信號量的P、V操作要成對出現,但它們分別在不同的進程代碼中。
典型理解偏差
三個問題:
一,以V原語的1、2步來做,Sem不就永遠大於0,那進程不就一直循環執行成為死循環了?
二,Sem大於0那就表示有臨界資源可供使用,為什麼不喚醒進程?
三,Sem小於0應該是說沒有臨界資源可供使用,為什麼還要喚醒進程?
析疑:
一,P操作對sem減1的。P、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,表明有進程阻塞在該類資源上,於是喚醒一個。
為了進一步加深理解,再引入 二個問題:
四,如果是互斥信號量的話,應該設定信號量Sem=1,但是當有5個進程都訪問的話,最後在該信號量的鍊表里會有4個在等待,也是說S=-4,那么第一個進程執行了V操作使S加1,釋放了資源,下一個應該能夠執行,但喚醒的這個進程在執行P操作時因S〈0,也還是執行不了,這是怎么回事呢?
五,Sem的絕對值表示等待的進程數,同時又表示臨界資源,這到底是怎么回事?
析疑:
四,當一個進程阻塞了的時候,它已經執行過了P操作,並卡在臨界區那個地方。當喚醒它時就立即進入它自己的臨界區,並不需要執行P操作了,當執行完了臨界區的程式後,就執行V操作。
五,當信號量Sem小於0時,其絕對值表示系統中因請求該類資源而被阻塞的進程數目.S大於0時表示可用的臨界資源數。注意在不同情況下所表達的含義不一樣。當等於0時,表示剛好用完。