1、熟悉并發(fā)程序?qū)嶒?yàn)工具BACI。 2、掌握BACC和BAINTERP的使用。 3、熟悉信號量的同步控制機(jī)制。 二、實(shí)驗(yàn)軟硬件要求 ??1、CPU:P4 1.6GHz?? 內(nèi)存:4G ? 2、Windows平臺上的Linux虛擬機(jī)
(1)完成Linux系統(tǒng)的登錄,啟動進(jìn)入終端。 編程步驟: ?? cd baci/balnxxe ?? 編寫程序文件命令:gedit my.cm (程序源碼請看第(2)題,需要你補(bǔ)充缺失的代碼。) ?? 編譯命令:$./bacc my,生成my.pco文件; 運(yùn)行:./bainterp my.pco,? 得到并分析結(jié)果。 (2)用信號量實(shí)現(xiàn)進(jìn)程同步時(shí),通常設(shè)置與進(jìn)程相關(guān)的私有信號量。empty和full分別屬于生產(chǎn)者和消費(fèi)者進(jìn)程私有,即生產(chǎn)者要問是否empty,才能開始生產(chǎn);同理,消費(fèi)者要問是否full才能消費(fèi)。 用信號量mutex實(shí)現(xiàn)進(jìn)程互斥,互斥使用緩沖池,其初值=1; 請將下面的并發(fā)程序填寫完整,或自行編寫并發(fā)程序。 參考程序:pc.cm semaphore mutex=1;????????????????????? //緩沖池互斥信號量 semaphore full=0;?????????????????????? //滿緩沖區(qū)個(gè)數(shù)信號量,初值=0 semaphore em=7;?????????? ??????????????//空緩沖區(qū)個(gè)數(shù)信號量,初值=7 int in=0;int out=0;???????????????????? int buff[6];??????????????????????????? //緩沖池 void p1() {?? int nextp; while(1) ? { cin>>nextp;???????????????????????? //生產(chǎn)一個(gè)產(chǎn)品 ??? p(em); ??? //填寫代碼 ???? buff[in]=nextp;??????????? ??????? ??? cout <<"in="<<in<<endl; ??? //填寫代碼; ??? cout <<"nextp="<<nextp<<endl; ?? v(mutex); ? //填寫代碼; ?? } ? }//producer void c1() {? int nextc;??????????????????????? ? while(1) ? { ??? //填寫代碼; ??? p(mutex); ?? ?? //填寫代碼 ?? out=(out+1)%6; ?? cout <<"nextc="<<nextc<<endl; ? ?//填寫代碼; ?? v(em); ? } }//consumer void main() { cobegin{? p1();c1(); } } 完整代碼: semaphore mutex=1; semaphore full=0; semaphore em=7; int in=0;int out=0; int buff[6]; void p1(){ ?? int nextp; ?? while(1){ ?????? cin>>nextp; ?????? p(em); ?????? p(mutex); ?????? buff[in]=nextp; ?????? cout<<"in="<<in<<endl; ?????? in=(in+1)%6; ?????? cout<<"nextp="<<nextp<<endl; ?????? v(mutex); ?????? v(full); ?? } } void c1(){ ?? int nextc; ?? while(1){ ?????? p(full); ?????? p(mutex); ?????? nextc=buff[out]; ?????? out=(out+1)%6; ?????? cout<<"nextc="<<nextc<<endl; ?????? v(mutex); ?????? v(em); ?? } }//consumer void main(){ cobegin{ ?? p1(); ?? c1(); ?? } } (3)有父親、母親、兒子、女兒4個(gè)進(jìn)程,共享一個(gè)盤子,父親每次在盤子中放入一個(gè)蘋果,盤子中的蘋果只能由女兒取出;母親每次向盤子放入一個(gè)桔子,桔子只能由兒子取出,假設(shè)盤子內(nèi)能裝一個(gè)水果。編程:apple.cm 1)編寫用信號量機(jī)制實(shí)現(xiàn)父親等4個(gè)進(jìn)程的并發(fā)控制程序; 2)在BACI環(huán)境中運(yùn)行并分析結(jié)果。 semaphore mutex=1; semaphore plat=1; semaphore apple=0; semaphore orange=0 ; int ap=0;int or=0;int pl=1; void father(){ ??? int num; ??? while(1){ ??? p(plat); ??? p(mutex); ??? cin>>num; ??? cout<<"father put on apple "<<num<<endl; ??? v(apple); ??? ap++; ??? pl--; ??? v(mutex); ?? } } void monther(){ ??? int num; ??? while(1){ ??? p(plat); ??? p(mutex); ??? cin>>num; ??? cout<<"monther put on orange "<<num<<endl; ??? v(orange); ??? or++; ??? pl--; ?? ?v(mutex); ?? ?? } } void son(){ ??? int num; ??? while(1){ ??? p(orange); ??? p(mutex); ??? cout<<"son take out a orange"<<endl; ??? v(plat); ??? or--; ??? pl++; ??? cout<<"orange="<<or<<endl; ??? cout<<"plat="<<pl<<endl; ??? v(mutex); ??? ??? ??????? } } void daughter(){ ??? int num; ??? while(1){ ??? ??? p(apple); ??? p(mutex); ??? cout<<"daughter take out a apple"<<endl; ??? v(plat); ??? ap--; ??? pl++; ??? cout<<"apple="<<ap<<endl; ??? cout<<"plat="<<pl<<endl; ??? v(mutex); ??? ?????? ? } } void main(){ ?? cobegin{ ?? father(); ?? daughter(); ?? monther(); ?? son(); ?? ?? } } 三、實(shí)驗(yàn)結(jié)果分析 (對上述實(shí)驗(yàn)內(nèi)容中的各題結(jié)果,進(jìn)行分析討論。并回答下列問題)
當(dāng)進(jìn)程互斥時(shí)或者涉及臨界資源的爭奪時(shí),應(yīng)該遵循前P后V的信號量設(shè)置原則
當(dāng)進(jìn)程同步時(shí),應(yīng)該遵循前V后P的原則,即先發(fā)生的進(jìn)程完成后設(shè)置V信號量,后發(fā)生的進(jìn)程發(fā)生前設(shè)置P信號量,同時(shí)注意,PV信號量應(yīng)該成對出現(xiàn)。 四、總結(jié):你對本次實(shí)驗(yàn)有什么體會或看法。 分析信號量問題時(shí),應(yīng)該先進(jìn)行關(guān)系分析,找出同步和互斥的關(guān)系,根據(jù)同步關(guān)系前V后P ,互斥關(guān)系前P后V的原則對信號量進(jìn)行設(shè)置。 注意:偽代碼中設(shè)置的semaphore是信號量,只能用PV進(jìn)行加減,不能使用++或—進(jìn)行操作。 附BACI工具說明: BACI提供了一個(gè)可以編寫并發(fā)程序的環(huán)境,在這個(gè)平臺上,我們可以很容易的模擬程序的并發(fā)執(zhí)行,在這種并行的編譯環(huán)境中,可以把BACI中的一些語句嵌入到C++,C,Java等高等程序中,使程序可以并行執(zhí)行 . 基于C++的BACI語法(C—BACI Compiler) 該語法結(jié)構(gòu)是在C++語法結(jié)構(gòu)的基礎(chǔ)上,增加一些并發(fā)語句擴(kuò)展而來,下面是在試驗(yàn)中需要用到的函數(shù)解釋. 1. cobegin函數(shù) 在BACI系統(tǒng)中,并發(fā)進(jìn)程與并發(fā)線程同步,多個(gè)進(jìn)程可以并發(fā)的在cobegin 塊中來并發(fā)執(zhí)行,該函數(shù)必須在主函數(shù)中,語法結(jié)構(gòu)為: cobegin { proc1(...);proc2(...);. . . . procN(...); } 其中每個(gè)進(jìn)程并發(fā)隨機(jī)執(zhí)行,每次執(zhí)行的順序可能會不一樣,當(dāng)所有的進(jìn)程接受后,該函數(shù)結(jié)束。 2. Semaphores/Binarysem 信號量的(Semaphores)機(jī)制可以更方便的實(shí)現(xiàn)進(jìn)程同步,Semaphores是一種如C中”int”一樣的類型,可以用來定義信號量類型的變量,Binarysem是一種二進(jìn)制信號量,它所定義的變量只能取1或 0,用來表示互斥。 1)信號量的聲明和初始化 semaphores a; binarysem s; 上面聲明了兩個(gè)信號量a,b,其中b為二進(jìn)制信號量信號量按如下方式初始化: Initialsem(semaphores,interger); Initialsem(binarysem,0/1); 2)P(wait)/V(signal)函數(shù) 強(qiáng)大的PV操作與信號量一次很方便的解決了并發(fā)進(jìn)程同步與互斥問題 函數(shù)原型: void p(semaphores &s); or void wait(semaphores &s); void v(semaphores &s); or void signal(semaphores &s); 函數(shù)說明: p(sem): 如果sem > 0,則sem減1,調(diào)用P的進(jìn)程可以繼續(xù)執(zhí)行,如果sem=0,則該進(jìn)程阻塞,該函 數(shù)操作是原子性的. v(sem): 如果v=0,或有進(jìn)程阻塞,則將其喚醒,如果沒有進(jìn)程等待,將sem加1,在任何時(shí)候調(diào)用 v的進(jìn)程可以繼續(xù)執(zhí)行,其操作也是原子的. 3.atomic atomic關(guān)鍵字定義了原子操作,即該函數(shù)操作不可剝奪,每次只能一個(gè)進(jìn)程訪問 用法:在要原子執(zhí)行的函數(shù)前加atomic即可,如: atomic int sum(){ . . . .. } 則sum()函數(shù)就可以原子操作了 4.void suspend(void) suspend函數(shù)將調(diào)用的線程掛起 5.void revive (int process_number) 該函數(shù)用于喚醒某個(gè)進(jìn)程,其進(jìn)程號為process_number文章來源:http://www.zghlxwxcb.cn/news/detail-741752.html 6.cin可以連續(xù)從鍵盤讀取想要的數(shù)據(jù),以空格、tab或換行作為分隔符。文章來源地址http://www.zghlxwxcb.cn/news/detail-741752.html |
到了這里,關(guān)于操作系統(tǒng)原理及安全 3-并發(fā)程序設(shè)計(jì)(綜合型)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!