Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評(píng)論 :: 0 Trackbacks
          PV原語操作詳解
          ?
            PV原語通過操作信號(hào)量來處理進(jìn)程間的同步與互斥的問題。其核心就是一段不可分割不可中斷的程序。 信號(hào)量的概念1965年由著名的荷蘭計(jì)算機(jī)科學(xué)家Dijkstra提出,其基本思路是用一種新的變量類型(semaphore)來記錄當(dāng)前可用資源的數(shù)量。
          ?
          ??? semaphore有兩種實(shí)現(xiàn)方式:
          ?
          ??? 1) semaphore的取值必須大于或等于0。0表示當(dāng)前已沒有空閑資源,而正數(shù)表示當(dāng)前空閑資源的數(shù)量;
          ??? 2) semaphore的取值可正可負(fù),負(fù)數(shù)的絕對(duì)值表示正在等待進(jìn)入臨界區(qū)的進(jìn)程個(gè)數(shù)。
          ?
          ??? 信號(hào)量是由操作系統(tǒng)來維護(hù)的,用戶進(jìn)程只能通過初始化和兩個(gè)標(biāo)準(zhǔn)原語(P、V原語)來訪問。初始化可指定一個(gè)非負(fù)整數(shù),即空閑資源總數(shù)。
          ?
          ??? P原語P是荷蘭語Proberen(測試)的首字母。為阻塞原語,負(fù)責(zé)把當(dāng)前進(jìn)程由運(yùn)行狀態(tài)轉(zhuǎn)換為阻塞狀態(tài),直到另外一個(gè)進(jìn)程喚醒它。操作為:申請(qǐng)一個(gè)空閑資源(把信號(hào)量減1),若成功,則退出;若失敗,則該進(jìn)程被阻塞;
          ?
          ??? V原語V是荷蘭語Verhogen(增加)的首字母。為喚醒原語,負(fù)責(zé)把一個(gè)被阻塞的進(jìn)程喚醒,它有一個(gè)參數(shù)表,存放著等待被喚醒的進(jìn)程信息。操作為:釋放一個(gè)被占用的資源(把信號(hào)量加1),如果發(fā)現(xiàn)有被阻塞的進(jìn)程,則選擇一個(gè)喚醒之。
          ?
          ??? P原語操作的動(dòng)作是:
          ??? (1)sem減1;
          ??? (2)若sem減1后仍大于或等于零,則進(jìn)程繼續(xù)執(zhí)行;
          ??? (3)若sem減1后小于零,則該進(jìn)程被阻塞后進(jìn)入與該信號(hào)相對(duì)應(yīng)的隊(duì)列中,然后轉(zhuǎn)進(jìn)程調(diào)度。
          ??? V原語操作的動(dòng)作是:
          ??? (1)sem加1;
          ??? (2)若相加結(jié)果大于零,則進(jìn)程繼續(xù)執(zhí)行;
          ??? (3)若相加結(jié)果小于或等于零,則從該信號(hào)的等待隊(duì)列中喚醒一等待進(jìn)程,然后再返回原進(jìn)程繼續(xù)執(zhí)行或轉(zhuǎn)進(jìn)程調(diào)度。

          ??? PV操作對(duì)于每一個(gè)進(jìn)程來說,都只能進(jìn)行一次,而且必須成對(duì)使用。在PV原語執(zhí)行期間不允許有中斷的發(fā)生。
          ?
          ?
          ---------------------------------------------
          ?
          ??? 具體PV原語對(duì)信號(hào)量的操作可以分為三種情況:
          ?
          ??? 1) 把信號(hào)量視為一個(gè)加鎖標(biāo)志位,實(shí)現(xiàn)對(duì)一個(gè)共享變量的互斥訪問。
          ?
          ??? 實(shí)現(xiàn)過程:
          ?
          ??? P(mutex); // mutex的初始值為1 訪問該共享數(shù)據(jù);
          ??? V(mutex);
          ??? 非臨界區(qū);
          ?
          ??? 2) 把信號(hào)量視為是某種類型的共享資源的剩余個(gè)數(shù),實(shí)現(xiàn)對(duì)一類共享資源的訪問。
          ?
          ??? 實(shí)現(xiàn)過程:
          ?
          ??? P(resource); // resource的初始值為該資源的個(gè)數(shù)N 使用該資源;
          ??? V(resource);
          ??? 非臨界區(qū);
          ?
            3) 把信號(hào)量作為進(jìn)程間的同步工具
          ?
          ??? 實(shí)現(xiàn)過程:
          ?
          ??? 臨界區(qū)C1;
          ??? P(S);
          ??? V(S);
          ??? 臨界區(qū)C2;
          ?
          ?
          ---------------------------------------------
          ?
          舉例說明:
          ?
          ?
          ??? 例1:某超市門口為顧客準(zhǔn)備了100輛手推車,每位顧客在進(jìn)去買東西時(shí)取一輛推車,在買完東西結(jié)完帳以后再把推車還回去。試用P、V操作正確實(shí)現(xiàn)顧客進(jìn)程的同步互斥關(guān)系。
          ?
          ??? 分析:把手推車視為某種資源,每個(gè)顧客為一個(gè)要互斥訪問該資源的進(jìn)程。因此這個(gè)例子為PV原語的第二種應(yīng)用類型。
          ?
          ??? 解:
          ?
          semaphore S_CartNum;?? ?// 空閑的手推車數(shù)量,初值為100
          void? consumer(void)??? // 顧客進(jìn)程
          {
          ??? P(S_CartNum);
          ?? 買東西;
          ?? 結(jié)帳;
          ?? V(S_CartNum);
          }
          ?
          ?
          ??? 例2:桌子上有一個(gè)水果盤,每一次可以往里面放入一個(gè)水果。爸爸專向盤子中放蘋果,兒子專等吃盤子中的蘋果。把爸爸、兒子看作二個(gè)進(jìn)程,試用P、V操作使這兩個(gè)進(jìn)程能正確地并發(fā)執(zhí)行。
          ?
          ??? 分析:爸爸和兒子兩個(gè)進(jìn)程相互制約,爸爸進(jìn)程執(zhí)行完即往盤中放入蘋果后,兒子進(jìn)程才能執(zhí)行即吃蘋果。因此該問題為進(jìn)程間的同步問題。
          ?
          ??? 解:
          ?
          semaphore? S_PlateNum;? // 盤子容量,初值為1
          semaphore? S_AppleNum;? // 蘋果數(shù)量,初值為0
          void? father( )? // 父親進(jìn)程
          {
          ??? while(1)
          ??? {
          ??????? P(S_PlateNum);
          ??????? 往盤子中放入一個(gè)蘋果;
          ??????? V(S_AppleNum);
          ??? }
          }
          void? son( )?? // 兒子進(jìn)程
          {
          ??? while(1)
          ??? {
          ??????? P(S_AppleNum);
          ??????? 從盤中取出蘋果;
          ??????? V(S_PlateNum);
          ??????? 吃蘋果;
          ??? }
          }
          ?
          ---------------------------------------------
          ?
          ??? 另附用PV原語解決進(jìn)程同步與互斥問題的例子:
          ?
          ???
          ??? 例3兩個(gè)進(jìn)程PA、PB通過兩個(gè)FIFO(先進(jìn)先出)緩沖區(qū)隊(duì)列連接(如圖)
          ??? PV
          ??? PA從Q2取消息,處理后往Q1發(fā)消息;PB從Q1取消息,處理后往Q2發(fā)消息,每個(gè)緩沖區(qū)長度等于傳送消息長度。 Q1隊(duì)列長度為n,Q2隊(duì)列長度為m. 假設(shè)開始時(shí)Q1中裝滿了消息,試用P、V操作解決上述進(jìn)程間通訊問題。
          ?
          ??? 解:
          ?
          // Q1隊(duì)列當(dāng)中的空閑緩沖區(qū)個(gè)數(shù),初值為0
          semaphore? S_BuffNum_Q1;??
          // Q2隊(duì)列當(dāng)中的空閑緩沖區(qū)個(gè)數(shù),初值為m
          semaphore? S_BuffNum_Q2;????
          // Q1隊(duì)列當(dāng)中的消息數(shù)量,初值為n
          semaphore? S_MessageNum_Q1;
          // Q2隊(duì)列當(dāng)中的消息數(shù)量,初值為0
          semaphore? S_MessageNum_Q2;
          ?
          void PA( )
          {
          ??? while(1)
          ??? {
          ??????? P(S_MessageNum_Q2);
          ??????? 從Q2當(dāng)中取出一條消息;
          ??????? V(S_BuffNum_Q2);
          ??????? 處理消息;
          ??????? 生成新的消息;
          ??????? P(S_BuffNum_Q1);
          ??????? 把該消息發(fā)送到Q1當(dāng)中;
          ??????? V(S_MessageNum_Q1);
          ??? }
          }
          ?
          void PB( )
          {
          ??? while(1)
          ??? {
          ??????? P(S_MessageNum_Q1);
          ??????? 從Q1當(dāng)中取出一條消息;
          ??????? V(S_BuffNum_Q1);
          ??????? 處理消息;
          ??????? 生成新的消息;
          ??????? P(S_BuffNum_Q2);
          ??????? 把該消息發(fā)送到Q2當(dāng)中;
          ??????? V(S_MessageNum_Q2);
          ??? }
          }
          ?
          ?
          ??? 例4:《操作系統(tǒng)》課程的期末考試即將舉行,假設(shè)把學(xué)生和監(jiān)考老師都看作進(jìn)程,學(xué)生有N人,教師1人。考場門口每次只能進(jìn)出一個(gè)人,進(jìn)考場的原則是先來先進(jìn)。當(dāng)N個(gè)學(xué)生都進(jìn)入了考場后,教師才能發(fā)卷子。學(xué)生交卷后即可離開考場,而教師要等收上來全部卷子并封裝卷子后才能離開考場。
          ??? (1)問共需設(shè)置幾個(gè)進(jìn)程?
          ??? (2)請(qǐng)用P、V操作解決上述問題中的同步和互斥關(guān)系。
          ?
          ??? 解:
          ?
          semaphore? S_Door;???????? // 能否進(jìn)出門,初值1
          semaphore? S_StudentReady; // 學(xué)生是否到齊,初值為0
          semaphore? S_ExamBegin;?? // 開始考試,初值為0
          semaphore? S_ExamOver;??? // 考試結(jié)束,初值為0
          ?
          int nStudentNum = 0;?????? // 學(xué)生數(shù)目
          semaphore? S_Mutex1;?????? //互斥信號(hào)量,初值為1
          int? nPaperNum = 0;?????? // 已交的卷子數(shù)目
          semaphore? S_Mutex2;?????? //互斥信號(hào)量,初值為1
          ?
          void? student( )
          {
          ??? P(S_Door);
          ??? 進(jìn)門;
          ??? V(S_Door);
          ??? P(S_Mutex1);
          ??? nStudentNum ++;?? // 增加學(xué)生的個(gè)數(shù)
          ??? if(nStudentNum == N)? V(S_StudentReady);
          ??? V(S_Mutex1);
          ??? P(S_ExamBegin);? // 等老師宣布考試開始
          ??? 考試中…
          ??? 交卷;
          ??? P(S_Mutex2);
          ??? nPaperNum ++;??? // 增加試卷的份數(shù)
          ??????? if(nPaperNum == N)?
          ??????? V(S_ExamOver);
          ??????? V(S_Mutex2);
          ??????? P(S_Door);
          ??????? 出門;
          ??????? V(S_Door);
          }
          ?
          void? teacher( )
          {
          ??? P(S_Door);
          ??? 進(jìn)門;
          ??? V(S_Door);
          ??? P(S_StudentReady);??? //等待最后一個(gè)學(xué)生來喚醒
          ??? 發(fā)卷子;
          ??????? for(i = 1; i <= N; i++)???
          ??????? V(S_ExamBegin);
          ??????? P(S_ExamOver);??? //等待考試結(jié)束
          ??????? 封裝試卷;
          ??????? P(S_Door);
          ??????? 出門;
          ??????? V(S_Door);
          }
          ?
          ?
          ?
          ??? 5某商店有兩種食品A和B,最大數(shù)量均為m個(gè)。 該商店將A、B兩種食品搭配出售,每次各取一個(gè)。為避免食品變質(zhì),遵循先到食品先出售的原則。有兩個(gè)食品公司分別不斷地供應(yīng)A、B兩種食品(每次一個(gè))。為保證正常銷售,當(dāng)某種食品的數(shù)量比另一種的數(shù)量超過k(k<m)個(gè)時(shí),暫停對(duì)數(shù)量大的食品進(jìn)貨,補(bǔ)充數(shù)量少的食品。
          ??? (1) 問共需設(shè)置幾個(gè)進(jìn)程?
          ??? (2) 用P、V操作解決上述問題中的同步互斥關(guān)系。
          ?
          ??? 解:
          ?
          semaphore? S_BuffNum_A;? //A的緩沖區(qū)個(gè)數(shù), 初值m
          semaphore? S_Num_A;????? // A的個(gè)數(shù),初值為0
          semaphore? S_BuffNum_B;? //B的緩沖區(qū)個(gè)數(shù), 初值m
          semaphore? S_Num_B;????? // B的個(gè)數(shù),初值為0
          ?
          void? Shop( )
          {
          ??? while(1)
          ??? {
          ??????? P(S_Num_A);
          ??????? P(S_Num_B);
          ??????? 分別取出A、B食品各一個(gè);
          ??????? V(S_BuffNum_A);
          ??????? V(S_BuffNum_A);
          ??????? 搭配地銷售這一對(duì)食品;
          ??? }
          }
          ?
          // “A食品加1,而B食品不變”這種情形允許出現(xiàn)的次數(shù)(許可證的數(shù)量),其值等于//k-(A-B),初值為k
          semaphore? S_A_B;
          // “B食品加1,而A食品不變”這種情形允許出現(xiàn)的次數(shù)(許可證的數(shù)量),其值等于//k-(B-A),初值為k
          semaphore? S_B_A;
          ?
          void? Producer_A( )
          {
          ??? while(1)
          ??? {
          ??????? 生產(chǎn)一個(gè)A食品;
          ??????? P(S_BuffNum_A);
          ??????? P(S_A_B);
          ??????? 向商店提供一個(gè)A食品;
          ??????? V(S_Num_A);
          ??????? V(S_B_A);
          ??? }
          }
          ?
          void? Producer_B( )
          {
          ??? while(1)
          ??? {
          ??????? 生產(chǎn)一個(gè)B食品;
          ??????? P(S_BuffNum_B);
          ??????? P(S_B_A);
          ??????? 向商店提供一個(gè)B食品;
          ??????? V(S_Num_B);
          ??????? V(S_A_B);
          ??? }
          }
          ?
          ?
          ??? 6:在一棟學(xué)生公寓里,只有一間浴室,而且這間浴室非常小,每一次只能容納一個(gè)人。公寓里既住著男生也住著女生,他們不得不分享這間浴室。因此,樓長制定了以下的浴室使用規(guī)則:
          ??? (1)每一次只能有一個(gè)人在使用;
          ??? (2)女生的優(yōu)先級(jí)要高于男生,即如果同時(shí)有男生和女生在等待使用浴室,則女生優(yōu)先;
          ??? (3)對(duì)于相同性別的人來說,采用先來先使用的原則。
          ?
          ??? 假設(shè):
          ??? (1)當(dāng)一個(gè)男生想要使用浴室時(shí),他會(huì)去執(zhí)行一個(gè)函數(shù)boy_wants_to_use_bathroom,當(dāng)他離開浴室時(shí),也會(huì)去執(zhí)行另外一個(gè)函數(shù)boy_leaves_bathroom;
          ??? (2)當(dāng)一個(gè)女生想要使用浴室時(shí),會(huì)去執(zhí)行函數(shù)girl_wants_to_use_bathroom,當(dāng)她離開時(shí), 也會(huì)執(zhí)行函數(shù)girl_leaves_bathroom;
          ?
          ??? 問題:請(qǐng)用信號(hào)量和P、V操作來實(shí)現(xiàn)這四個(gè)函數(shù)(初始狀態(tài):浴室是空的)。
          ?
          ??? 解:
          ?
          信號(hào)量的定義:
          semaphore? S_mutex;? // 互斥信號(hào)量,初值均為1
          semaphore? S_boys; ? // 男生等待隊(duì)列,初值為0
          semaphore? S_girls; // 女生等待隊(duì)列,初值為0
          ?
          普通變量的定義:
          int? boys_waiting = 0;? // 正在等待的男生數(shù);
          int? girls_waiting = 0; // 正在等待的女生數(shù);
          int? using = 0;???? ?? // 當(dāng)前是否有人在使用浴室;
          ?
          void? boy_wants_to_use_bathroom ( )
          {
          ??? P(S_mutex);
          ??? if((using == 0) && (girls_waiting == 0))
          ??????? {
          ??????????? using? =? 1;
          ??????????? V(S_mutex);
          ??????? }
          ??? else
          ??????? {
          ??????????? boys_waiting ++;
          ??????????? V(S_mutex);
          ??????????? P(S_boys);
          ??????? }
          }
          ?
          void? boy_leaves_bathroom ( )
          {
          ??? P(S_mutex);
          ??? if(girls_waiting? >? 0)? // 優(yōu)先喚醒女生
          ??????? {
          ??????????? girls_waiting --;
          ??????????? V(S_girls);
          ??????? }
          ??? else? if(boys_waiting? >? 0)
          ??????? {
          ??????????? boys_waiting --;
          ??????????? V(S_ boys);
          ??????? }
          ??????? else???
          ??????????? using? =? 0;???? // 無人在等待
          ??????? ??? V(S_mutex);
          }
          ?
          void? girl_wants_to_use_bathroom ( )
          {
          ??? P(S_mutex);
          ??? if(using == 0)
          ??? {
          ??????? using? =? 1;
          ??????? V(S_mutex);
          ??? }
          ??? else
          ??? {
          ??????? girls_waiting ++;
          ??????? V(S_mutex);
          ??????? P(S_girls);
          ??? }
          }
          ?
          void? girl_leaves_bathroom ( )
          {
          ??? P(S_mutex);
          ??? if(girls_waiting? >? 0)? // 優(yōu)先喚醒女生
          ??? {
          ??????? girls_waiting --;
          ??????? V(S_girls);
          ??? }
          ??? else? if(boys_waiting? >? 0)
          ??????? {
          ??????????? boys_waiting --;
          ??????????? V(S_ boys);
          ??????? }
          ??????? else???
          ??????????? using? =? 0;???? // 無人在等待
          ??????????? V(S_mutex);
          }
          ?
          ?
          ?
          ?
          ?
          ?
          ?
          ?
          再附上幾個(gè)例子:
          ********************************************************************************************************
          ?
          用PV原語實(shí)現(xiàn)進(jìn)程的互斥

            由于用于互斥的信號(hào)量sem與所有的并發(fā)進(jìn)程有關(guān),所以稱之為公有信號(hào)量。公有信號(hào)量的值反映了公有資源的數(shù)量。只要把臨界區(qū)置于P(sem)和V(sem)之間,即可實(shí)現(xiàn)進(jìn)程間的互斥。就象火車中的每節(jié)車廂只有一個(gè)衛(wèi)生間,該車廂的所有旅客共享這個(gè)公有資源:衛(wèi)生間,所以旅客間必須互斥進(jìn)入衛(wèi)生間,只要把衛(wèi)生間放在P(sem)和V(sem)之間,就可以到達(dá)互斥的效果。以下例子說明進(jìn)程的互斥實(shí)現(xiàn)。

          例1:
          ??? 生產(chǎn)圍棋的工人不小心把相等數(shù)量的黑子和白子混裝載一個(gè)箱子里,現(xiàn)要用自動(dòng)分揀系統(tǒng)把黑子和白子分開,該系統(tǒng)由兩個(gè)并發(fā)執(zhí)行的進(jìn)程組成,功能如下:
          ??? (1)進(jìn)程A專門揀黑子,進(jìn)程B專門揀白子;
          ??? (2)每個(gè)進(jìn)程每次只揀一個(gè)子,當(dāng)一個(gè)進(jìn)程在揀子時(shí)不允許另一個(gè)進(jìn)程去揀子;
          ?
          ??? 分析:
          ??? 第一步:確定進(jìn)程間的關(guān)系。由功能(2)可知進(jìn)程之間是互斥的關(guān)系。
          ??? 第二步:確定信號(hào)量及其值。由于進(jìn)程A和進(jìn)程B要互斥進(jìn)入箱子去揀棋子,箱子是兩個(gè)進(jìn)程的公有資源,所以設(shè)置一個(gè)信號(hào)量s,其值取決于公有資源的數(shù)目,由于箱子只有一個(gè),s的初值就設(shè)為1。
          ?
          ??? 實(shí)現(xiàn):
          begin
          ??? s:semaphore;
          ??? s:=1;
          ??? cobegin
          ??????? process A
          ??????? begin
          ??????????? L1: P(s);
          ??????????? 揀黑子;
          ??????????? V(s);
          ??????????? goto L1;
          ??????? end;
          ??????? process B
          ??????? begin
          ??????????? L2:P(s);
          ??????????? 揀白子;
          ??????????? V(s);
          ??????????? goto L2;
          ??????? end;
          ??? coend;
          end;
          ?
            判斷進(jìn)程間是否互斥,關(guān)鍵是看進(jìn)程間是否共享某一公有資源,一個(gè)公有資源與一個(gè)信號(hào)量相對(duì)應(yīng)。確定信號(hào)量的值是一個(gè)關(guān)鍵點(diǎn),它代表了可用資源實(shí)體數(shù)。如下實(shí)例:
          ?
          ?
          例2:
          ??? 某車站售票廳,任何時(shí)刻最多可容納20名購票者進(jìn)入,當(dāng)售票廳中少于20名購票者時(shí),廳外的購票者可立即進(jìn)入,否則需要在外面等待。每個(gè)購票者可看成一個(gè)進(jìn)程。
          ?
          ??? 分析:第一步:確定進(jìn)程間的關(guān)系。售票廳是各進(jìn)程共享的公有資源,當(dāng)售票廳中多于20名購票者時(shí),廳外的購票者需要在外面等待。所以進(jìn)程間是互斥的關(guān)系。第二步:確定信號(hào)量及其值。只有一個(gè)公有資源:售票廳,所以設(shè)置一個(gè)信號(hào)量s。售票廳最多容納20個(gè)進(jìn)程,即可用資源實(shí)體數(shù)為20,s的初值就設(shè)為20。
          ?
          ??? 實(shí)現(xiàn):
          ?
          begin
          ??? s:semaphore;
          ??? s:=20;
          ??? cobegin
          ??????? process PI(I=1,2,……)
          ??????? begin P(s);
          ??????????? 進(jìn)入售票廳;
          ??????????? 購票;
          ??????????? 退出;
          ??????????? V(s);
          ??????? end;
          ??? coend;
          end;
          ?
          ??? 當(dāng)購票者進(jìn)入售票廳前要執(zhí)行P(s)操作,執(zhí)行后若s大于或等于零,說明售票廳的人數(shù)還未滿可進(jìn)入。執(zhí)行后若s小于零,則說明售票廳的人數(shù)已滿不能進(jìn)入。這個(gè)實(shí)現(xiàn)中同時(shí)最多允許20個(gè)進(jìn)程進(jìn)入售票廳購票,其余進(jìn)程只能等待。
          ?
          用PV原語實(shí)現(xiàn)進(jìn)程的同步

            與進(jìn)程互斥不同,進(jìn)程同步時(shí)的信號(hào)量只與制約進(jìn)程及被制約進(jìn)程有關(guān)而不是與整組并發(fā)進(jìn)程有關(guān),所以稱該信號(hào)量為私有信號(hào)量。利用PV原語實(shí)現(xiàn)進(jìn)程同步的方法是:首先判斷進(jìn)程間的關(guān)系為同步的,且為各并發(fā)進(jìn)程設(shè)置私有信號(hào)量,然后為私有信號(hào)量賦初值,最后利用PV原語和私有信號(hào)量規(guī)定各進(jìn)程的執(zhí)行順序。下面我們將例1增添一個(gè)條件,使其成為進(jìn)程間是同步的。

          例3:
          ??? 在例1的基礎(chǔ)之上再添加一個(gè)功能:
            (3)當(dāng)一個(gè)進(jìn)程揀了一個(gè)棋子(黑子或白子)以后,必讓另一個(gè)進(jìn)程揀一個(gè)棋子(黑子或白子)。
          ?
          ??? 分析:
          ??? 第一步:確定進(jìn)程間的關(guān)系。由功能(1)(2)(3)可知,進(jìn)程間的關(guān)系為同步關(guān)系。第二步:確定信號(hào)量及其值。進(jìn)程A和B共享箱子這個(gè)公有資源,但規(guī)定兩個(gè)進(jìn)程必須輪流去取不同色的棋子,因而相互間要互通消息。對(duì)于進(jìn)程A可設(shè)置一個(gè)私有信號(hào)量s1,該私有信號(hào)量用于判斷進(jìn)程A是否能去揀黑子,初值為1。對(duì)于進(jìn)程B同樣設(shè)置一個(gè)私有信號(hào)量s2,該私有信號(hào)量用于判斷進(jìn)程B是否能去揀白子,初值為0。當(dāng)然你也可以設(shè)置s1初值為0,s2初值為1。
          ?
          ??? 實(shí)現(xiàn):
          ?
          begin
          ??? s1,s2:semaphore;
          ??? s1:=1;s2:=0;
          ??? cobegin
          ??????? process A
          ??????? ??? begin
          ??????? ??? L1: P(s1);
          ??????? ??? 揀黑子;
          ??????? ??? V(s2);
          ??????? ??? goto L1;
          ??????? end;???
          ??????? process B
          ??????? begin
          ??????????? L2:P(s2);
          ??????????? 揀白子;
          ??????????? V(s1);
          ??????????? goto L2;
          ??????? end;
          ??? coend;
          end;
          ?

            另外一個(gè)問題就是P原語是不是一定在V原語的前面?回答是否定的。下面看一個(gè)例子:

          例4:
          ??? 設(shè)在公共汽車上,司機(jī)和售票員的活動(dòng)分別是:司機(jī):啟動(dòng)車輛,正常行車,到站停車。售票員:上乘客,關(guān)車門,售票,開車門,下乘客。用PV操作對(duì)其控制。
          ?
          ??? 分析:
          ??? 第一步:確定進(jìn)程間的關(guān)系。司機(jī)到站停車后,售票員方可工作。同樣,售票員關(guān)車門后,司機(jī)才能工作。所以司機(jī)與售票員之間是一種同步關(guān)系。
          ??? 第二步:確定信號(hào)量及其值。由于司機(jī)與售票員之間要互通消息,司機(jī)進(jìn)程設(shè)置一個(gè)私有信號(hào)量run,用于判斷司機(jī)能否進(jìn)行工作,初值為0。售票員進(jìn)程設(shè)置一個(gè)私有信號(hào)量stop,用于判斷是否停車,售票員是否能夠開車門,初值為0。
          ??? 實(shí)現(xiàn):
          begin
          ??? stop ,run:semaphore
          ??? stop:=0;run:=0;
          ??? cobegin
          ??????? driver:
          ??????? begin
          ??????????? L1: P(run);
          ??????????? 啟動(dòng)車輛;
          ??????????? 正常行車;
          ??????????? 到站停車;
          ??????????? V(stop);
          ??????????? goto L1;
          ??????? end;
          ??????? conductor:
          ??????? begin
          ??????????? L2:上乘客;
          ??????????? 關(guān)車門;
          ??????????? V(run);
          ??????????? 售票;
          ??????????? P(stop);
          ??????????? 開車門;
          ??????????? 下乘客;
          ??????????? goto L2;
          ??????? end;
          ??? coend;
          end;
          ?
            用PV操作還可以實(shí)現(xiàn)進(jìn)程同步與互斥的混合問題,典型的如:多個(gè)生產(chǎn)者和多個(gè)消費(fèi)者共享容量為n的緩存區(qū)。這個(gè)例子在很多書中都有介紹,在這里就不說了。
          ?
          ?
          posted on 2009-05-10 21:12 decode360 閱讀(521) 評(píng)論(0)  編輯  收藏 所屬分類: 01.IT_Base
          主站蜘蛛池模板: 鹤山市| 阿图什市| 当阳市| 原平市| 三江| 大连市| 绥江县| 盱眙县| 乡城县| 文山县| 景宁| 新河县| 东台市| 米易县| 富民县| 高尔夫| 武夷山市| 应城市| 台北县| 同心县| 任丘市| 黎城县| 阿克苏市| 类乌齐县| 民乐县| 田林县| 哈尔滨市| 临汾市| 桐梓县| 新乡县| 木兰县| 丰宁| 沈丘县| 镇宁| 原阳县| 和静县| 丰镇市| 奉新县| 遂宁市| 自贡市| 平安县|