進程的同步、互斥以及PV原語

操作系統P,V(wait,signal原語)操作講解,以及兩個例題(答案僅供參考)

操作系統的pv操作是很核心的概念。

臨界區 : 我們把併發進程中與共享變量有關的程序段稱爲臨界區。

信號量 : 信號量的值與相應資源的使用情況有關。當它的值大於0時,表示當前可用資源的數量;當它的值小於0時,其絕對值表示等待使用該資源的進程個數。

進程的互斥:是指當有若干個進程都要使用某一共享資源時,任何時刻最多隻允許一個進程去使用該資源,其他要使用它的進程必須等待,直到該資源的佔用着釋放了該資源。
進程的同步:是指在併發進程之間存在這一種制約關係,一個進程依賴另一個進程的消息,當一個進程沒有得到另一個進程的消息時應等待,直到消息到達才被喚醒。

pv操作又稱wait,signal原語。
主要是操作進程中對進程控制的信息量的加減控制。

wait用法:
wait(num),num是目標參數,wait的作用是使其(信息量)減一。
如果信息量>=0,則該進程繼續執行;否則該進程置爲等待狀態,排入等待隊列。
signal用法:
signal(num),num是目標參數,signal的作用是使其(信息量)加一。
如果信息量>0,則該進程繼續執行;否則釋放隊列中第一個等待信號量的進程。
————————————————
版權聲明:本文爲CSDN博主「緣之妙不可言」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/thebestway/article/details/105034840

 

進程的同步、互斥以及PV原語

在處理進程間的同步與互斥問題時,我們離不開信號量和PV原語,使用這兩個工具的目的在於打造一段不可分割不可中斷的程序。應當注意的是,信號量和PV原語是解決進程間同步與互斥問題的一種機制,但並不是唯一的機制。

信號量:

信號量的概念1965年由著名的荷蘭計算機科學家 Edsger Wybe Dijkstra 艾茲格·迪科斯徹 提出。

其核心思想是用一種新的變量類型(Semaphore)來記錄可用資源的數量。有兩種實現方式:

1、Semaphore的取值必須大於或等於0。0表示當前已經沒有空閒資源,而正數表示當前空閒資源的數量;

2、Semaphore的取值可正可負,負數的絕對值表示正在等待進入臨界區的進程個數;

信號量是一個二元組(S,Q)。S是一個具有非負初值的整型變量,Q是一個初始狀態爲空的隊列。

PV原語

P原語:P是荷蘭語Proberen(測試)的首字母。爲阻塞原語,負責把當前進程由運行狀態轉換爲阻塞狀態,直到另一個進程喚醒它。具體操作爲:申請一個空閒資源(把信號量減1),若成功,則退出;若失敗,則該進程被阻塞。

V原語:V是荷蘭語Verhogen(增加)的首字母。爲喚醒原語,負責把一個被阻塞的進程喚醒,他有一個參數表,存放着等待被喚醒的進程信息。具體操作爲:釋放一個被佔用的資源(把信號量加1),如果發現有被阻塞的進程,則選擇一個喚醒。

表示方法

P(S):表示將信號量S的值減一,即S=S-1;如果S>=0,則該進程繼續執行,否則該進程置爲等待狀態,排入等待隊列(隊列Q)。

V(S):表示將信號量S的值加一,即S=S+1;如果S>0,則該進程繼續執行,否則釋放隊列(Q)中第一個等待信號量的進程。

    PV操作對於每一個進程來說,都只能進行一次,而且必須成對使用。在PV原語執行期間不允許有中斷的發生。

實現互斥模型

在互斥模型中,多個進程對可用資源進行爭用,使用信號量S表示可用資源的數量。一般來說,信號量S>=0時,S表示可用資源的數量。執行一次P操作意味着請求分配一個單位資源,因此S的值減1;當S<0時,表示已經沒有可用資源,請求者必須等待別的進程釋放該類資源,它才能運行下去。而執行一個V操作意味着釋放一個單位資源,因此S的值加1;若S<=0,表示有某些進程正在等待該資源,因此要喚醒一個等待狀態的進程,使之運行下去。

進程互斥是進程之間發生的一種間接性作用,一般是程序不希望的。

如下表所示,我們使用S=1做爲初值,表示當前系統資源只有一個,多個進程需要輪流使用這個資源。

image

在互斥模型的問題中,關鍵的問題在於使用PV操作來保證有限的系統資源被正常的使用和釋放,而不是多人爭搶誰都搶不到,或者某人獨佔而不釋放的情況。有點類似於北京現在的搖號制度,實際上資源就是兩萬個號牌,每個申請的人都執行了一次P操作,表示自己想要使用資源,在搖號結果出來之前沒有資源可用,大家都進入Q隊列等候,放號之時,獲得資格的用戶執行V操作,釋放一個等待位置,其他人可以進入下一次的排號等候隊列。

實現同步模型

所謂同步,是指多個相互合作的進程,在一些關鍵點上可能需要相互等待或相互交換信息,這種互相制約的關係稱爲進程同步。例如系統中有兩個合作的進程,他們共用一個單緩衝區。這兩個進程一個是計算進程,負責對數據進行計算;另一個爲打印進程,負責對計算結果進行打印。當計算進程沒有計算完畢,計算結果沒有送到緩衝區的時候,打印進程就不能打印。一旦計算進程把計算結果送入緩衝區,就應該給打印進程發送一個信號,打印進程收到信號後就可以從緩衝區中取出計算結果進行打印。

之前我在想這個同步模型的時候,考慮可以使用定時輪詢的方式,計算進程定時查詢緩衝區,可用即開始寫入;打印進程定時查詢緩衝區,有內容即開始打印。但是這種沒有相互合作溝通的方式,非常容易出現問題,比如計算進程內容還沒有寫完,打印進程就開始讀取打印,造成分頁的不正確或者數據的不完整。實際上,一般我們都會有多個計算進程,這種情況下就會同時存在資源爭用的問題。

 

進程同步是進程之間直接的相互作用,是合做進程間有意識的行爲。與互斥模型不同,進程同步時的信號量只與制約進程、被制約進程有關而不是與所有的同類併發進程有關,所以同步模型中的信號量爲私有信號量。

生產者-消費者模型是同步模型的典型代表,其也存在多種情況,分別敘述如下:

1、一個生產者,一個消費者,共用一個緩衝區。

定義兩個同步信號量,生產者需要一個EMPTY信號量來判斷當前是否能夠寫入,設置初值爲1,消費者需要一個FULL信號量,來判斷當前是否能夠讀取,設置初值爲0。

image

2、一個生產者,一個消費者,共用N個緩衝區。

與上面的例子不同的是,EMPTY的初值爲N,則生產者的阻塞時間會減少很多。

image

3、多個生產者,多個消費者,共用N個緩衝區。

在這種場景下,除了同步之外,還需要在生產者之間、消費者之間進行互斥的訪問緩衝區,所以需要設置四個信號量,分別是EMPTY、FULL、生產者之間的互斥信號量Mutex1、消費者之間的互斥信號量Mutex2。

非生產者、消費者模型的例子有一個司機和售票員的。設置RUN信號量供司機判斷是否應該開車,初始值爲0;設置STOP信號量供售票員判斷是否可以開門,初始值爲0。描述如下:

image

前驅圖(Precedence Graph)是一種有向無循環圖,記爲DAG(Directed Acyclic Graph),用於描述進程間執行的前後關係。如下圖:

image

圖中的每個結點可用於描述一個進程段或進程,乃至一條語句;結點間的有向邊則用於表示兩個結點之間存在的偏序(Partial Order)或前驅關係。可以使用PV原語,來描述前驅圖。

PS:互斥的問題可以用硬件方法解決,如何解決,不太清楚。

參考資料:

1、Process Synchronization PV

2、Linux死鎖淺談

3、Linux的多線程編程的高效開發經驗

4、百度百科PV原語

5、PV原語

6、PV原語解釋

7、PV原語實現進程的同步與互斥

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章