旌旗燈號量:整型、記載型旌旗燈號量以及應用旌旗燈號量完成過程互斥和前驅關係

旌旗燈號量機構是一種功用較強的機制,可用來處理互斥與同步的成績,它只能被兩個規範的原語wait(S)和signal(S)來拜訪,也可以記爲“P操作”和“V操作”。
原語是指完成某種功用且不被聯繫不被中綴履行的操作序列,平日可由硬件來完成完成不被聯繫履行特徵的功用。如前述的“Test-and-Set”和“Swap”指令,就是由硬件完成的原子操作。原語功用的不被中綴履行特徵在單處置機時可由軟件經過屏障中綴辦法完成。
原語之所以不克不及被中綴履行,是由於原語對變量的操作進程假如被打斷,能夠會去運轉另一個對統一變量的操作進程,從而呈現臨界段成績。假如可以找到一種處理臨界段成績的元辦法,就可以完成對共享變量操作的原子性。

整型旌旗燈號量

整型旌旗燈號量被界說爲一個用於表現資本數量的整型量S,wait和signal操作可描繪爲:

			wait(S){ while (S<=0); S=S-1; } signal(S){ S=S+1; }

wait操作中,只需旌旗燈號量S<=0,就會不時地測試。因而,該機制並未遵照“讓權等候” 的原則,而是使過程處於“忙等”的形態。

記載型旌旗燈號量

記載型旌旗燈號量是不存在“忙等”景象的過程同步機制。除了需求一個用於代表資本數量的整型變量value外,再添加一個過程鏈表L,用於鏈接一切等候該資本的過程,記載型旌旗燈號量是因爲釆用了記載型的數據構造得名。記載型旌旗燈號量可描繪爲:

			typedef struct{ int value; struct process *L; } semaphore;

響應的wait(S)和signal(S)的操作如下:

			void wait (semaphore S) { //相當於請求資本 S.value--; if(S.value<0) { add this process to S.L; block(S.L); } }

wait操作,S.value--,表現過程懇求一個該類資本,當S.value<0時,表現該類資本已分派終了,因而過程應挪用block原語,停止自我壅塞,保持處置機,並拔出到該類資本的等候隊列S.L中,可見該機制遵照了“讓權等候”的原則。

			void signal (semaphore S) { //相當於釋放資本 S.value++; if(S.value<=0){ remove a process P from S.L; wakeup(P); } }

signal操作,表現過程釋放一個資本,使零碎中可供分派的該類資本數增1,故S.value++。若加1後仍是S.value<=0,則表現在S.L中仍有等候該資本的過程被壅塞,故還應挪用wakeup 原語,將S.L中的第一個等候過程叫醒。

應用旌旗燈號量完成同步

旌旗燈號量機構能用於處理過程間各類同步成績。設S爲完成過程P1、P2同步的公共旌旗燈號量,初值爲0。過程P2中的語句y要運用過程P1中語句x的運轉後果,所以只要當語句x履行完成之後語句y纔可以履行。其完成過程同步的算法如下:

			semaphore S = 0; //初始化旌旗燈號量 P1 ( ) { // … x; //語句x V(S); //通知過程P2,語句乂曾經完成 } P2()){ // … P(S) ; //反省語句x能否運轉完成 y; // 反省無誤,運轉y語句 // … }

應用旌旗燈號量完成過程互斥

旌旗燈號量機構也能很便利地處理過程互斥成績。設S爲完成過程Pl、P2互斥的旌旗燈號量,因爲每次只許可一個過程進入臨界區,所以S的初值應爲1(即可用資本數爲1)。只需把臨界區置於P(S)和V(S)之間,即可完成兩過程對臨界資本的互斥拜訪。其算法如下:

			semaphore S = 1; //初化旌旗燈號量 P1 ( ) { // … P(S); // 預備開端拜訪臨界資本,加鎖 // 過程P1的臨界區 V(S); // 拜訪完畢,解鎖 // … } P2() { // … P(S); //預備開端拜訪臨界資本,加鎖 // 過程P2的臨界區; V(S); // 拜訪完畢,解鎖 // … }

互斥的完成是分歧過程對統一旌旗燈號量停止P、V操作,一個過程在勝利地對旌旗燈號量履行了 P操作落後入臨界區,並在加入臨界區後,由該過程自身對該旌旗燈號量履行V操作,表現以後沒有過程進入臨界區,可以讓其他過程進入。

應用旌旗燈號量完成前驅關係

旌旗燈號量也可以用來描繪程序之間或許語句之間的前驅關係。圖2-8給出了一個前驅圖,箇中S1, S2, S3, …, S6是最複雜的程序段(只要一條語句)。爲使各程序段能準確履行,應設置若干個初始值爲“0”的旌旗燈號量。例如,爲包管S1 -> S2、 S1 -> S3的前驅關係,應辨別設相信號量a1、a2。異樣,爲了包管 S2 -> S4、S2 ->S5、S3 -> S6、S4 -> S6、S5 -> S6,應設相信號量bl、b2、c、d、e。 


圖2-8 前驅圖舉例


完成算法如下:

			semaphore al=a2=bl=b2=c=d=e=0; //初始化旌旗燈號量 S1() { // … V(al); V(a2) ; //S1曾經運轉完成 } S2() { P(a1); //反省S1能否運轉完成 // … V(bl); V(b2); // S2曾經運轉完成 } S3() { P(a2); //反省S1能否曾經運轉完成 // … V(c); //S3曾經運轉完成 } S4() { P(b1); //反省S2能否曾經運轉完成 // … V(d); //S4曾經運轉完成 } S5() { P(b2); //反省S2能否曾經運轉完成 // … V(e); // S5曾經運轉完成 } S6() { P(c); //反省S3能否曾經運轉完成 P(d); //反省S4能否曾經運轉完成 P(e); //反省S5能否曾經運轉完成 // …; }

剖析過程同步和互斥成績的辦法步調

1) 關係剖析。找出成績中的過程數,而且剖析它們之間的同步和互斥關係。同步、互斥、前驅關係直接依照下面例子中的經模範式改寫。
2) 整頓思緒。找出處理成績的癥結點,而且依據做過的標題找出處理的思緒。依據過程的操作流程肯定P操作、V操作的大致次序。
3) 設相信號量。依據下面兩步,設置需求的旌旗燈號量,肯定初值,完美整頓。


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