信號量機(jī)制及實現(xiàn)進(jìn)程的互斥、同步

??進(jìn)程互斥的四種軟件實現(xiàn)方式(單標(biāo)志法沐绒、雙標(biāo)志先檢查法俩莽、雙標(biāo)志后檢查法、以及Peterson算法)乔遮,三種硬件實現(xiàn)方式(中斷屏蔽方法扮超、TSL指令、Swap指令)蹋肮。在所有的解決方案中都無法實現(xiàn)讓權(quán)等待問題出刷。

1 信號量機(jī)制

??信號量機(jī)制是一種可以實現(xiàn)進(jìn)程互斥、同步的有效方法坯辩。
??信號量其實就是一個變量(可以是一個整數(shù)馁龟,也可以是更復(fù)雜的記錄型變量),可以用一個信號量來表示系統(tǒng)中某種資源的數(shù)量漆魔。如系統(tǒng)中只有一臺打印機(jī)坷檩,就可以設(shè)置一個初值為1的信號量。如所有的臨界資源在同一時刻只能被一個進(jìn)程訪問改抡,所以臨界資源的信號量為1矢炼。
??用戶進(jìn)程可以通過使用操作系統(tǒng)提供的一對原語來對信號量進(jìn)行操作,從而很方便的實現(xiàn)了進(jìn)程的互斥和同步阿纤。
??一對原語:wait(S)原語和signal(S)原語句灌,S表示信號量。wait阵赠、signal原語通常稱為P涯塔、V 操作肌稻。

2 信號量機(jī)制——整型信號量

??用一個整數(shù)型的變量作為信號量,用來表示系統(tǒng)某種資源的數(shù)量匕荸。
??如:某計算機(jī)系統(tǒng)中只有一臺打印機(jī)...

int S = 1; //初始化整型信號量S爹谭,表示當(dāng)前系統(tǒng)中可用的打印機(jī)資源。
void wait(int S){ //wait原語榛搔,相當(dāng)于“進(jìn)入?yún)^(qū)”
  while(S <= 0));    // 如果資源不夠诺凡,就一直循環(huán)等待
   S = S - 1;      // 如果資源數(shù)夠,則占用一個資源
}

void signal(int S){ // signal原語践惑,相當(dāng)于“退出區(qū)”
  S = S + 1;          // 使用完資源后腹泌,在退出區(qū)釋放資源
}

??使用原語將檢查和上鎖變成了原子性操作,避免了并發(fā)尔觉、異步導(dǎo)致的問題凉袱。
??存在問題:不滿足讓權(quán)等待原則,會發(fā)生忙等侦铜。

3 信號量機(jī)制——記錄型信號

??整型信號量的缺點是存在忙等的問題专甩,所以又提出了記錄型信號量。

/*記錄型信號量的定義*/
typedef struct{
  int value;         // 剩余資源
  struct process *L;  // 等待隊列钉稍,當(dāng)沒有資源剩余時涤躲,新來的進(jìn)程將會被放在這個阻塞隊列中
} semaphore

/* 某進(jìn)程需要使用資源時,通過wait原語申請*/
void wait(semaphore S) {
  S.value--;
  if(S.value < 0)   // 如果剩余資源不夠贡未,使用block原語使進(jìn)程從運行態(tài)進(jìn)入阻塞態(tài)种樱,
      block(S.L);  // 并掛到信號量的等待隊列中。
}

/* 進(jìn)程使用完資源后俊卤,通過signal原語釋放*/
void signal(semaphore S) {
  S.value++;
  if(S.value <= 0) // 如果value的值小于0嫩挤,表示有新的進(jìn)程在等待資源,所以要喚醒等待隊列中的進(jìn)程
      wakeup(S.L);
}

(1) 對信號量S的一次P操作意味著進(jìn)程請求一個單位該類的資源瘾蛋,需要執(zhí)行S.value--俐镐,表示資源數(shù)減1矫限,當(dāng)S.value < 0時表示該類資源已經(jīng)分配完畢哺哼,因此進(jìn)程應(yīng)該調(diào)用block原語進(jìn)行自我阻塞(當(dāng)前運行的進(jìn)程從運行態(tài)—>阻塞態(tài)),主動放棄處理機(jī)叼风,并插入到該類資源的等待隊列S.L中取董。可見无宿,該機(jī)制遵循了“讓權(quán)等待”原則茵汰,不會出現(xiàn)忙等現(xiàn)象。
(2) 對信號量S的一次V操作意味著進(jìn)程釋放了一個單位的該類資源孽鸡,因此需要執(zhí)行S.value++蹂午,表示該類資源加1栏豺,若加1后仍是S.value <= 0,表示依然有進(jìn)程在等待該類資源豆胸,因此應(yīng)調(diào)用wakeup原語喚醒等待隊列中第一個進(jìn)程(被喚醒進(jìn)程從阻塞態(tài)—>就緒態(tài))奥洼。

4 信號量機(jī)制實現(xiàn)進(jìn)程互斥

(1) 確定臨界區(qū)(如對臨界資源打印機(jī)的訪問就應(yīng)放在臨界區(qū))
(2) 設(shè)置互斥信號量(mutex)。
(3) 在臨界區(qū)之前執(zhí)行P(mutex)
(4) 在臨界區(qū)之后執(zhí)行V(mutex)

/* 信號量機(jī)制實現(xiàn)互斥 */
semaphore mutex = 1; // 初始化信號量

P1(){
  ...
  P(mutex);   // 使用臨界資源前需要加鎖
  臨界區(qū)代碼段.....
  V(mutex);   // 使用臨界資源后需要解鎖
  ...
}

P2(){
  ...
  P(mutex);  
  臨界區(qū)代碼段.....
  V(mutex);   
  ...
}
.....

5 信號量機(jī)制實現(xiàn)進(jìn)程同步

??進(jìn)程同步:就是要讓并發(fā)進(jìn)程按要求有序的推進(jìn)晚胡。
??用信號量實現(xiàn)進(jìn)程同步:

(1) 分析需要同步的兩個操作灵奖,即必須保證一前一后的執(zhí)行順序的操作。
(2) 設(shè)置同步信號量S估盘,初始為0瓷患。
(3) 在前操作之后執(zhí)行V(S)。
(4) 在后操作之前執(zhí)行P(S)遣妥。

??如P1擅编、P2并發(fā)執(zhí)行,假設(shè)需要保證代碼4必須要代碼1和代碼2的運行結(jié)果才能執(zhí)行箫踩,那么就必須保證代碼4必須在代碼2之后執(zhí)行沙咏。

P1(){
  代碼1;
  代碼2;
  代碼3;
}

P2(){
  代碼4;
  代碼5;
  代碼6;
}

??使用信號量機(jī)制實現(xiàn)同步

semaphore S = 0; //初始化同步信號量,初始值為0;
P1(){                           P2(){
    代碼1;                        P(s)
    代碼2;                        代碼4;
    V(S);                         代碼5;
    代碼3;                        代碼6;
}                               }

(1) 若先執(zhí)行到V(S)操作班套,則S++后S=1,肢藐。之后執(zhí)行到P(S)時,由于S=1吱韭,表示有資源吆豹,執(zhí)行S--后,S的值為0理盆,P2不會執(zhí)行block原語痘煤,而是繼續(xù)往下執(zhí)行代碼4。
(2) 若先執(zhí)行到P(S)操作猿规,由于S=0衷快,S--后S=-1,表示沒有資源姨俩,因此P操作會執(zhí)行block原語蘸拔,主動請求阻塞。之后當(dāng)執(zhí)行完代碼2环葵,繼而執(zhí)行V(S)操作调窍,S++,S的值變?yōu)?张遭,由于此時有進(jìn)程在該信號量的阻塞隊列中邓萨,因此V操作會執(zhí)行wakeup原語,喚醒P2進(jìn)程,這樣P2進(jìn)程就可以繼續(xù)執(zhí)行代碼4了缔恳。
無論是哪種情況宝剖,都可以保證代碼4一定在代碼2之后執(zhí)行。

6 信號量機(jī)制實現(xiàn)前驅(qū)關(guān)系

??進(jìn)程P1中有句代碼S1歉甚,P2中有句代碼S2...诈闺,這些代碼要求按照如下的順序執(zhí)行:



??其實每一對前驅(qū)關(guān)系都是一個進(jìn)程同步問題(需要保證一前一后的操作),因此:

(1) 要為每一對前驅(qū)關(guān)系各設(shè)置一個同步變量铃芦。
(2) 在前操作之后對應(yīng)的同步變量執(zhí)行V操作雅镊。
(3) 在后操作之前對應(yīng)的同步變量執(zhí)行P操作。


??對應(yīng)的代碼如下:


本文完

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刃滓,一起剝皮案震驚了整個濱河市仁烹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咧虎,老刑警劉巖卓缰,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砰诵,居然都是意外死亡征唬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門茁彭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來总寒,“玉大人,你說我怎么就攤上這事理肺∩阏ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵妹萨,是天一觀的道長年枕。 經(jīng)常有香客問我,道長乎完,這世上最難降的妖魔是什么熏兄? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮树姨,結(jié)果婚禮上摩桶,老公的妹妹穿的比我還像新娘。我一直安慰自己娃弓,他們只是感情好典格,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布岛宦。 她就那樣靜靜地躺著台丛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挽霉,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天防嗡,我揣著相機(jī)與錄音,去河邊找鬼侠坎。 笑死蚁趁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的实胸。 我是一名探鬼主播他嫡,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼庐完!你這毒婦竟也來了钢属?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤门躯,失蹤者是張志新(化名)和其女友劉穎淆党,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讶凉,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡染乌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了懂讯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荷憋。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖褐望,靈堂內(nèi)的尸體忽然破棺而出台谊,到底是詐尸還是另有隱情,我是刑警寧澤譬挚,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布锅铅,位于F島的核電站,受9級特大地震影響减宣,放射性物質(zhì)發(fā)生泄漏盐须。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一漆腌、第九天 我趴在偏房一處隱蔽的房頂上張望贼邓。 院中可真熱鬧,春花似錦闷尿、人聲如沸塑径。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽统舀。三九已至匆骗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間誉简,已是汗流浹背碉就。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留闷串,地道東北人瓮钥。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像烹吵,于是被迫代替她去往敵國和親碉熄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354