上面的文章講解了在Windows系統下實現多線程同步互斥的方法,為了提高在實際問題中分析和思考多個線程之間同步互斥問題的能力,接下來將講解PV操作,這也是操作系統中的重點和難點。本文將會先簡要介紹下PV操作的來源和基本使用方法,然后再通過兩道經典的計算機考研真題——放水果和安全島來示范如何運用PV操作。
?
先講講PV操作的起源和用法。
1962年,荷蘭學者Dijksrta在參與X8計算機的開發中設計并實現了具有多道程序運行能力的操作系統——THE Multiprogramming System。為了解決這個操作系統中進程(線程)的同步與互斥問題,他巧妙地利用火車運行控制系統中的“信號燈”(semaphore,或叫“信號量”)概念加以解決。信號量的值大于0時,表示當前可用資源的數量;當它的值小于0時,其絕對值表示等待使用該資源的進程個數。注意,這個信號量的值僅能由PV操作來改變。
PV操作由P操作原語和V操作原語組成(原語也叫原子操作Atomic Operation,是不可中斷的過程),對信號量(注意不要和Windows中的信號量機制相混淆)進行操作,具體定義如下:
P(S):
①將信號量S的值減1,即S=S-1;
②如果S>=0,則該進程繼續執行;否則該進程置為等待狀態。
V(S):
①將信號量S的值加1,即S=S+1;
②該進程繼續執行;如果該信號的等待隊列中有等待進程就喚醒一等待進程。
?
用PV操作實現多線程的同步與互斥是非常簡單的,只要考慮邏輯處理上合理嚴密而不用考慮具體技術細節,因此與寫偽代碼較為相似。比如有多個進程P1、P2、 ……PN。它們要互斥的訪問一個資源。用PV操作來實現就非常方便直觀。下面是PV操作代碼:
設置信號量為S,初值為1。各進程的操作流程如下:
進程P1??????????????進程P2?????????? ……??????????進程Pn
P(S);????????????? P(S);????????????? ??????????? ?P(S);
訪問資源;?????????訪問資源;??????????????????????訪問資源;
V(S);???????????? V(S);??????????????????????? ??V(S);
可以看出PV操作會忽略具體的編程細節,讓程序員的主要精力放在線程同步互斥的邏輯處理上。因此,通過練習PV操作能快速有效提高程序員對多線程的邏輯思維能力,達到強化“內功”的目的。
?
接下來就來幾道簡單的計算機考研真題。
?
第一題 放水果 南京大學計算機考研真題
桌上有一空盤,允許存放一只水果。爸爸可向盤中放蘋果,也可向盤中放桔子,兒子專等吃盤中的桔子,女兒專等吃盤中的蘋果。規定當盤空時一次只能放一只水果供吃者取用,請用P、V原語實現爸爸、兒子、女兒三個并發進程的同步。
這個題目涉及的東西非常之多,光人物就有三個再加水果,盤子等等,確實讓人感覺好像無從下手。但不管題目如何變,只要牢牢的抓住同步和互斥來分析問題就必定能迎刃而解。
下面先考慮同步情況即所有“等待”情況:
第一.爸爸要等待盤子為空。
第二.兒子要等待盤中水果是桔子。
第三.女兒要等待盤中水果是蘋果。
接下來來考慮要互斥處理的資源,看起來盤子好像是要作互斥處理的,但由于題目中的爸爸、兒子、女兒均只有一個,并且他們訪問盤子的條件都不一樣,所以他們根本不會同時去訪問盤子,因此盤子也就不用作互斥處理了。分析至些,這個題目已經沒有難度了,下面用PV原語給出答案:
先設置三個信號量,信號量Orange表示盤中有桔子,初值為0。信號量Apple表示盤中有蘋果,初值為0。信號量EmptyDish表示盤子為空,初值為1。三個人的操作流程如下所示:
1.爸爸
P(EmptyDish)
if (rand()%2==0)
{???
??? 放桔子
??? V(Orange)
}
else
{
??? 放蘋果
?? ?V(Apple)
}
?
2.兒子
P(Orange)
取桔子
V(EmptyDish)
?
3.女兒
P(Apple)
取蘋果
V(EmptyDish)
?
?
第二題 安全島 南開大學考研真題
在南開大學至天津大學間有一條彎曲的路,每次只允許一輛自行車通過,但中間有小的安全島M(同時允許兩輛車),可供兩輛車在已進入兩端小車錯車,設計算法并使用P,V實現。
?
這個問題應該如何考慮了?同樣只要牢牢的抓住同步和互斥來分析問題就必定能迎刃而解。
考慮所有“等待”情況:
在路口N準備從N到T的人應該什么時候進入了?如果他只判斷道路K上有沒有人肯定是不行的,因為如果安全島M上已經有2個人,那么路口N和路口T再各進一人,肯定會造成死鎖。因此可以這樣——在路口N準備從N到T的人要等待與他同方向的人已經到達T,如果此人已經到達T,且道路K上沒有人,他必定可以上路了。同理在路口T準備從T到N的人也應該這樣做。
再考慮互斥情況:
路上每次只允許一輛自行車通過,所以道路是需要作互斥處理的。
?
分析之后,下面就用PV原語給出答案(考研輔導書上的答案):
設置信號量NT表示在路口N且從N到T方向上允許出發的自行車數量,初值為1。信號量TN表示在路口T且從T到N方向上允許出發的自行車數量,初值為1。信號量K和L表示道路,初值均為1。這樣從N到T的車和從T到N的車的行駛流程如下:
從N到T的車?????? ??????????????從T到N的車
P(NT)??????????????? P(TN)
P(K)???????????????? P(L)
由N到M???????????????由T到M
V(K)?????????????????V(L)
P(L)?????????????????P(K)
由M到T???????????????由M到T
V(L)?????????????????V(K)
V(NT)????????????????V(TN)
?
這個題目的解法有很多,比如還可以用信號量M來記錄安全島M上空位個數,初值為2。每個進入道路前的人都要先預訂安全島上的空位,訂到后再互斥的進入道路。否則就要等待安全島上有空位。信號量K和L表示道路,初值均為1。然后從N到T的車和從T到N的車的行駛流程如下:
從N到T的車?????????????????????從T到N的車
P(M)???????????????? P(M)
P(K)?????????????????P(L)
由N到M???????????????由T到M
V(K)?????????????????V(L)
P(L)?????????????????P(K)
V(M)?????????????????V(M)
由M到T???????????????由M到T
V(L)?????????????????V(K)
?
這種解決方法也是不會造成死鎖的。安全島的解法非常之多,網上還有不少不同的解法,有興趣的童鞋可以搜索一下。
?
下一篇將講解更難的一道PV操作題,歡迎大家參閱。