實驗七同步機構(gòu)_第1頁
實驗七同步機構(gòu)_第2頁
實驗七同步機構(gòu)_第3頁
實驗七同步機構(gòu)_第4頁
實驗七同步機構(gòu)_第5頁
已閱讀5頁,還剩13頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、實驗七:同步機構(gòu)實驗報告 一、實習內(nèi)容模擬實現(xiàn)用同步機構(gòu)避免發(fā)生進程執(zhí)行時可能出現(xiàn)的與時間有關(guān)的錯誤。二、實習目的進程是程序在一個數(shù)據(jù)集合上運行的過程,進程是并發(fā)執(zhí)行的,也即系統(tǒng)中的多個進程輪流地占用處理器運行。我們把若干個進程都能進行訪問和修改的那些變量稱為公共變量。由于進程是并發(fā)地執(zhí)行的,所以,如果對進程訪問公共變量不加限制,那么就會產(chǎn)生“與時間有關(guān)”的錯誤,即進程執(zhí)行后所得到的結(jié)果與訪問公共變量的時間有關(guān)。為了防止這類錯誤,系統(tǒng)必須要用同步機構(gòu)來控制進程對公共變量的訪問。一般說,同步機構(gòu)是由若干條原語同步原語所組成。本實習要求學生模擬PV操作同步機構(gòu)的實現(xiàn),模擬進程的并發(fā)執(zhí)行,

2、了解進程并發(fā)執(zhí)行時同步機構(gòu)的作用。三、實習題目模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者消費者問題。提示:(1) PV操作同步機構(gòu),由P操作原語和V操作原語組成,它們的定義如下:P操作原語P (s):將信號量s減去1,若結(jié)果小于0,則執(zhí)行原語的進程被置成等待信號量s的狀態(tài)。V操作原語V (s):將信號量s加1,若結(jié)果不大于0,則釋放一個等待信號量s的進程。這兩條原語是如下的兩個過程:procedure p (var s: semaphore);begin s: = s-1; if s<0 then W (s)end pprocedure v (var s: semaphore);egi

3、n s: = s+1; if s£0 then R (s)end v其中W(s)表示將調(diào)用過程的進程置為等待信號量s的狀態(tài);R(s)表示釋放一個等待信號量s的進程。在系統(tǒng)初始化時應把semaphore定義為某個類型,為簡單起見,在模擬實習中可把上述的semaphore直接改成integer。(2) 生產(chǎn)者消費者問題。假定有一個生產(chǎn)者和一個消費者,生產(chǎn)者每次生產(chǎn)一件產(chǎn)品,并把生產(chǎn)的產(chǎn)品存入共享緩沖器以供消費者取走使用。消費者每次從緩沖器內(nèi)取出一件產(chǎn)品去消費。禁止生產(chǎn)者將產(chǎn)品放入已滿的緩沖器內(nèi),禁止消費者從空緩沖器內(nèi)以產(chǎn)品。假定緩沖器內(nèi)可同時存放10件產(chǎn)品。那么,用PV操作來實現(xiàn)生產(chǎn)者和

4、消費者之間的同步,生產(chǎn)者和消費者兩個進程的程序如下:B: array 0.9 of products;s1, s2; semaphore;s1: =10, s2: =0;IN, out: integer;IN: =0; out: =0;cobegin procedure producer; c: products; beginL1: Produce (c); P (s1); BIN: =C; IN: =(IN+1)mod 10; V (s2); goto L1 end; procedure consumer; x: products; begin L2: p (s2); x: =Bout; o

5、ut: =(out+1) mod10; v (s1); consume (x); goto L2 end;coend.其中的semaphore和products是預先定義的兩個類型,在模擬實現(xiàn)中semaphore用integer代替,products可用integer或char等代替。(3) 進程控制塊PCB。為了記錄進程執(zhí)行時的情況,以及進程讓出處理器后的狀態(tài),斷點等信息,每個進程都有一個進程控制塊PCB。在模擬實習中,假設(shè)進程控制塊的結(jié)構(gòu)如圖12-1。其中進程的狀態(tài)有:運行態(tài)、就緒態(tài)、等待態(tài)和完成態(tài)。當進程處于等待態(tài)時,在進程控制塊PCB中要說明進程等待原因(在模擬實習中進程等待原因是為等

6、待信號量s1或s2);當進程處于等待態(tài)或就緒態(tài)時,PCB中保留了斷點信息,一旦進程再度占有處理器則就從斷點位置繼續(xù)運行;當進程處于完成狀態(tài),表示進程執(zhí)行結(jié)束。 進程名狀態(tài)等待原因斷點圖12-1 進程控制塊結(jié)構(gòu) (4) 處理器的模擬。計算機硬件提供了一組機器指令,處理器的主要職責是解釋執(zhí)行機器指令。為了模擬生產(chǎn)者和消費者進程的并發(fā)執(zhí)行,我們必須模擬一組指令和處理職能。模擬的一組指令見圖12-2,其中每條指令的功能由一個過程來實現(xiàn)。用變量PC來模擬“指令計數(shù)器”,假設(shè)模擬的指令長度為1,每執(zhí)行一條模擬指令后,PC加1,提出下一條指令地址。使用模擬的指令,可把生產(chǎn)者和消費者進程的

7、程序表示為圖12-3的形式。定義兩個一維數(shù)組PA0.4和SA0.4,每一個PAi存放生產(chǎn)者程序中的一條模擬指令執(zhí)行的入口地址;每個SAi存放消費者程序中的一條模擬指令執(zhí)行的入口地址。于是模擬處理器執(zhí)行一條指令的過程為:取出PC之值,按PAPC或SAPC得模擬指令執(zhí)行的入口地址,將PC之值加1,轉(zhuǎn)向由入口地址確定的相應的過程執(zhí)行。(5) 程序設(shè)計本實習中的程序由三部分組成:初始化程序、處理器調(diào)度程序、模擬處理器指令執(zhí)行程序。各部分程序的功能及相互間的關(guān)系由圖12-4至圖12-7指出。 模擬的指令功 能p (s) 執(zhí)行P操作原語v (s) 執(zhí)行V操作原語put BIN: =product

8、; IN: = (IN+1) mod 10GET x: =Bout; out: =(out+1) mod 10produce 輸入一個字符放入C中consume 打印或顯示x中的字符GOTO L PC: =LNOP 空操作圖12-2 模擬的處理器指令 序號生產(chǎn)者程序消費者程序0producep (s2)1p (s1)GET2PUTv (s1)3v (s2)consume4goto 0goto 0圖12-3 生產(chǎn)者和消費者程序 ·初始化程序:模擬實習的程序從初始化程序入口啟動,初始化工作包括對信號量s1、s2賦初值,對生產(chǎn)者、消費者進程的PCB初始化。·處

9、理器調(diào)度程序:在計算機系統(tǒng)中,進程并發(fā)執(zhí)行時,任一進程占用處理器執(zhí)行完一條指令后就有可能被打斷而讓出處理器由其它進程運行。故在模擬系統(tǒng)中也類似處理,每當執(zhí)行一條模擬的指令后,保護當前進程的現(xiàn)場,讓它成為非運行態(tài),由處理器調(diào)度程序按隨機數(shù)再選擇一個就緒進程占用處理器運行。四、實習報告(1) 實習題目。(2) 打印源程序并附上注釋。(3) 從鍵盤上輸入一組字符,由生產(chǎn)者每次讀入一個字符供消費者輸出。運行模擬程序,打印依次讀入的字符和經(jīng)消費者輸出的字符。(4) 把生產(chǎn)者和消費者進程中的P操作、V操作都改成空操作指令,觀察在兩者不同步的情況下可能出現(xiàn)的與時間有關(guān)的錯誤。打印依次讀入的字符和經(jīng)消費者輸出

10、的字符。 1)實驗題目:模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者消費者問題。2)實驗源代碼:分為四個頭文件。1、a.h頭文件代碼如下:#include<string.h> #include<ctype.h> #include<malloc.h> /* malloc()等 */ #include<limits.h> /* INT_MAX等 */ #include<stdio.h> /* EOF(=Z或F6),NULL */ #include<stdlib.h> /* atoi() */ #include<

11、io.h> /* eof() */ #include<math.h> /* floor(),ceil(),abs() */ #include<process.h> /* exit() */ #include <iostream> using namespace std; #include <time.h> #define BUF 10 /緩存的大小 #define MAX 20 /最大可以輸入的字符2、b.h頭文件代碼如下:/數(shù)據(jù)結(jié)構(gòu)的定義和全局變量typedef struct Pcb char name10; /進程名char state

12、10; /運行狀態(tài)char reason10; /若阻塞,其原因int breakp; /斷點保護struct Pcb *next; /阻塞時的順序Pcb,*link;int s1,s2; /信號量link p1;/生產(chǎn)者進程link c1;/消費者進程char strMAX; /輸入的字符串char bufferBUF; /緩沖池int len; /輸入長度int sp=0; /string的指針int in=0; /生產(chǎn)者指針int out=0; /消費者指針char temp; /供打印的臨時產(chǎn)品char rec_pMAX;/生產(chǎn)記錄int rp1=0;/生產(chǎn)記錄指針char rec_c

13、MAX;/消費記錄int rp2=0;/消費記錄指針link ready; /就緒隊列l(wèi)ink b_s1; /s1阻塞隊列l(wèi)ink b_s2; /s2阻塞隊列int pc; /程序計數(shù)器int count; /字符計數(shù)器int con_cnt; /消費計數(shù)器3、c.h頭文件代碼如下:void init(); /初始化void p(int s); /P操作void v(int s); /V操作void block(int s);/阻塞函數(shù)void wakeup(int s);/喚醒函數(shù)void control(); /處理機調(diào)度void processor();/處理機執(zhí)行void print(

14、); /打印函數(shù)void init() /初始化s1=BUF;s2=0;p1=(link)malloc(sizeof(Pcb);/建立新的結(jié)點,并初始化為生產(chǎn)者strcpy(p1->name,"Producer");strcpy(p1->state,"Ready");strcpy(p1->reason,"Null");p1->breakp=0;p1->next=NULL;c1=(link)malloc(sizeof(Pcb);/建立新的結(jié)點,并初始化為消費者strcpy(c1->name,"

15、;Consumer");strcpy(c1->state,"Ready");strcpy(c1->reason,"Null");c1->breakp=0;c1->next=NULL;ready=p1;ready->next=c1;/初始化為生產(chǎn)進程在前,消費進程在后c1->next=NULL;b_s1=NULL;b_s2=NULL;/阻塞進程為NULLpc=0;con_cnt=0; /消費計數(shù)器void p(int s)if(s=1) /p(s1)s1-;if(s1<0) block(1); /阻塞當前

16、生產(chǎn)進程elseprintf("t* s1信號申請成功!n");ready->breakp=pc; /保存斷點else /p(s2)s2-;if(s2<0) block(2);/阻塞當前消費進程elseprintf("t* s2信號申請成功!n");ready->breakp=pc; /保存斷點void v(int s)if(s=1) /v(s1)s1+;if(s1<=0)wakeup(1); /喚醒生產(chǎn)進程ready->breakp=pc; /保存斷點else /v(s2)s2+;if(s2<=0) wakeup(2

17、);/喚醒消費進程ready->breakp=pc; /保存斷點void block(int s)/阻塞函數(shù)的定義link p;int num1=0;int num2=0;if(s=1)/生產(chǎn)進程strcpy(p1->state,"Block");/改變狀態(tài)strcpy(p1->reason,"S1");/說明原因p=b_s1;while(p)num1+;p=p->next;/p的值為NULL,表示隊尾if(!b_s1)b_s1=p1;elsep=p1;p1->next=NULL;printf("t* p1生產(chǎn)進程

18、阻塞了!n");ready->breakp=pc; /保存斷點ready=ready->next;/在就緒隊列中去掉,指向下一個num1+;else/消費進程strcpy(c1->state,"Block");strcpy(c1->reason,"S2");p=b_s2;while(p)num2+;p=p->next;/p的值為NULL,表示隊尾if(!b_s2)b_s2=c1;elsep=c1;ready->breakp=pc; /保存斷點ready=ready->next;/在就緒隊列中去掉,指向下

19、一個c1->next=NULL;printf("t* c1消費進程阻塞了!n");num2+;printf("t* 阻塞的生產(chǎn)進程個數(shù)為:%dn",num1);printf("t* 阻塞的消費進程個數(shù)為:%dn",num2);void wakeup(int s)/喚醒函數(shù)的定義link p;link q=ready;if(s=1) /喚醒b_s1隊首進程,生產(chǎn)進程隊列p=b_s1;b_s1=b_s1->next;/阻塞指針指向下一個阻塞進程strcpy(p->state,"Ready");strc

20、py(p->reason,"Null");while(q)/插入就緒隊列q=q->next;q=p;p->next=NULL;printf("t* p1生產(chǎn)進程喚醒了!n");else /喚醒b_s2隊首進程,消費進程隊列p=b_s2;b_s2=b_s2->next;/阻塞指針指向下一個阻塞進程strcpy(p->state,"Ready");strcpy(p->reason,"Null");while(q->next)/插入就緒隊列q=q->next;q->n

21、ext=p;p->next=NULL;printf("t* c1消費進程喚醒了!n");void control() /處理器調(diào)度程序int rd;int num=0;link p=ready; if(ready=NULL) /若無就緒進程,結(jié)束return;while(p) /統(tǒng)計就緒進程個數(shù)num+;p=p->next;/最終p變?yōu)镹ULLprintf("t* 就緒進程個數(shù)為:%dn",num);time_t t; srand(unsigned) time(&t);rd=rand()%num;/隨機函數(shù)產(chǎn)生隨機數(shù)if(rd=1)p

22、=ready;ready=ready->next;ready->next=p;p->next=NULL;strcpy(ready->state,"Run");strcpy(ready->next->state,"Ready");else strcpy(ready->state,"Run");pc=ready->breakp;void processor() /模擬處理器指令執(zhí)行if(strcmp(ready->name,"Producer")=0) /當前進程為

23、生產(chǎn)者switch(pc) case 0:/produceprintf("t* 生產(chǎn)者生產(chǎn)了字符%cn",strsp);rec_prp1=strsp;/添加到生產(chǎn)記錄 sp=(sp+1)%len;pc+;ready->breakp=pc; /保存斷點break;case 1: /p(s1)pc+;p(1);break;case 2: /putbufferin=rec_prp1; /放到緩沖區(qū)printf("t* %c字符成功入駐空緩存!n",bufferin);rp1+; in=(in+1)%BUF;pc+;ready->breakp=pc;

24、 /保存斷點break;case 3: /v(s2)pc+;printf("t* 釋放一個s2信號n");v(2);break;case 4:/goto01 printf("t* 生產(chǎn)進程goto 0 操作n");pc=0;count-; /剩余字符個數(shù)減1printf("t* 剩余字符count=%d個n",count);ready->breakp=pc; /保存斷點if(count<=0) /生產(chǎn)結(jié)束printf("t* 生產(chǎn)者結(jié)束生產(chǎn)!n");strcpy(p1->state,"S

25、top");strcpy(p1->reason,"Null");ready->breakp=-1;ready=ready->next;/在就緒隊列中去掉 else /當前進程為消費者switch(pc)case 0: /p(s2)pc+;p(2); break;case 1: /getprintf("t* 消費者取字符!n");temp=bufferout;out=(out+1)%BUF;pc+;ready->breakp=pc; /保存斷點break;case 2: /v(s1)pc+;printf("t*

26、釋放一個s1n");v(1);break;case 3: /consumeprintf("t* 消費了字符%cn",temp);rec_crp2=temp;/添加到消費記錄rp2+;con_cnt+;if(con_cnt>=len)strcpy(c1->state,"Stop");/完成態(tài)c1->breakp=-1;return;pc+;ready->breakp=pc; /保存斷點break;case 4: /goto0printf("t* 消費進程goto 0 操作n");pc=0;ready->breakp=pc; /保存斷點void print()int i,j;printf("生產(chǎn)者消費者模擬n");printf("* 模擬過程的字符串為:t");printf("%sn",&str);printf("* 已生產(chǎn):");for(j=0;j<=rp1;j+)printf("%c",rec_pj);printf("n* 空緩存:");for(j=rp2;j<=rp1;j+)printf(&

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論