實驗七同步機構全解_第1頁
實驗七同步機構全解_第2頁
實驗七同步機構全解_第3頁
已閱讀5頁,還剩14頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

4、產品。那么,用 PV 操作來實現生產者和消費者 之間的同步,生產者和消費者兩個進程的程序如下:B: array 0.9 of products;s1, s2; semaphore;s1: =10, s2: =0;IN, out: in teger;IN: =0; out: =0;cobeg inprocedure producer;c: products;beg inL1:Produce (c);P (S1);BIN: =C;IN: =(IN+1)mod 10;V (s2);goto L1end;procedure con sumer;x: products;beg inL2:p (S2);x

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

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

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

8、N: =product; IN: = (IN+1) mod 10GETx: =Bout; out: =(out+1) mod 10produce輸入一個字符放入C中con sume打印或顯示x中的字符GOTO Lr pc: =lNOP空操作圖12-2 模擬的處理器指令序號生產者程序消費者程序0producep (S2)1p (s1)GET2PUTv (S1)3v (S2)con sume4goto 0goto 0圖12-3生產者和消費者程序初始化程序:模擬實習的程序從初始化程序入口啟動,初始化工作包括對信號量S1、S2賦初值,對生產者、消費者進程的 PCB初始化。處理器調度程序:在計算機系統中

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

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

11、() */ #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 頭文件代碼如下:/ 數據結構的定義和全局變量typedef struct Pcbchar name10;/ 進程名char state10; / 運行狀態char rea

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

13、ar rec_cMAX;/ 消費記錄 int rp2=0;/ 消費記錄指針 link ready; / 就緒隊列 link b_s1; /s1 阻塞隊列 link b_s2; /s2 阻塞隊列 int pc; / 程序計數器 int count; / 字符計數器 int con_cnt; / 消費計數器3、c.h 頭文件代碼如下:void init();/初始化void p(int s);/P操作void v(int s);/V操作void block(int s);/阻塞函數void wakeup(int s);/ 喚醒函數void control(); / 處理機調度void proces

14、sor();/ 處理機執行void print(); / 打印函數void init() / 初始化s1=BUF;s2=0;p1=(link)malloc(sizeof(Pcb);/ 建立新的結點 , 并初始化為生產者strcpy(p1->name,"Producer");strcpy(p1->state,"Ready");strcpy(p1->reason,"Null");p1->breakp=0;p1->next=NULL;c1=(link)malloc(sizeof(Pcb);/ 建立新的結點 ,

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

16、p(s1)s1-;if(s1<0)block(1); / 阻塞當前生產進程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); / 喚醒生產進程 ready->breakp=pc;

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

18、;elsep=p1;p1->next=NULL;printf("t* p1 生產進程阻塞了 !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;rea

19、dy->breakp=pc; / 保存斷點ready=ready->next;/ 在就緒隊列中去掉 , 指向下一個c1->next=NULL;printf("t* c1 消費進程阻塞了 !n");num2+;printf("t* 阻塞的生產進程個數為 :%dn",num1);printf("t* 阻塞的消費進程個數為 :%dn",num2);void wakeup(int s)/ 喚醒函數的定義link p;link q=ready;if(s=1) / 喚醒b_s1隊首進程,生產進程隊列p=b_s1;b_s1=b_s

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

21、ot;Null");while(q->next)/ 插入就緒隊列q=q->next;q->next=p;p->next=NULL;printf("t* c1 消費進程喚醒了 !n");void control() / 處理器調度程序int rd;int num=0;link p=ready;if(ready=NULL) / 若無就緒進程 , 結束return;while(p) / 統計就緒進程個數num+;printf("t* 就緒進程個數為 :%dn",num);time_t t; srand(unsigned) ti

22、me(&t);rd=rand()%num;/ 隨機函數產生隨機數 if(rd=1)p=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() / 模擬處理器指令執行 if(

23、strcmp(ready->name,"Producer")=0) /當前進程為生產者switch(pc)case 0:/produceprintf("t* 生產者生產了字符 %cn",strsp); rec_prp1=strsp;/ 添加到生產記錄 sp=(sp+1)%len;pc+;ready->breakp=pc; / 保存斷點break;case 1: /p(s1)pc+;p(1);break;case 2: /putbufferin=rec_prp1; / 放到緩沖區 printf("t* %c 字符成功入駐空緩存 !n&

24、quot;,bufferin); rp1+;in=(in+1)%BUF;pc+;ready->breakp=pc; / 保存斷點 break;case 3: /v(s2)pc+;printf("t*釋放一個 s2 信號n");v(2);break;case 4:/goto01printf("t* 生產進程 goto 0 操作 n");pc=0;count-; /剩余字符個數減 1printf("t*剩余字符 count=%d個n",count);ready->breakp=pc; / 保存斷點if(count<=0)

25、 / 生產結束printf("t* 生產者結束生產 !n"); strcpy(p1->state,"Stop"); 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

26、;pc+;ready->breakp=pc; / 保存斷點break;case 2: /v(s1)pc+;printf("t* 釋放一個 s1n");v(1);break;case 3: /consumeprintf("t* 消費了字符 %cn",temp); rec_crp2=temp;/ 添加到消費記錄 rp2+;con_cnt+;if(con_cnt>=len)strcpy(c1->state,"Stop");/ 完成態 c1->breakp=-1;return; pc+;ready->breakp

27、=pc; / 保存斷點 break;case 4: /goto0 printf("t* 消費進程 goto 0 操作 n"); pc=0;ready->breakp=pc; / 保存斷點void print()int i,j;printf(" 生產者消費者模擬 n"); printf("*模擬過程的字符串為 :t");printf("%sn",&str);printf("*已生產 :");for(j=0;j<=rp1;j+) printf("%c",rec

28、_pj);printf("n* 空緩存 :"); for(j=rp2;j<=rp1;j+) printf("%c",bufferj);printf("n* 已消費 :"); for(j=0;j<=rp2;j+) printf("%c",rec_cj);printf("n 進程控制塊的信息 n"); printf("進程名tt 狀態t等待原因t斷點n");printf("%st%st%stt%dnn",p1->name,p1->sta

29、te,p1->reason,p1->breakp);printf("%st%st%stt%dn",c1->name,c1->state,c1->reason,c1->bre akp);n");printf(" printf("1. 繼續 0. 退出 n"); scanf("%d",&i);if(i=0)exit(0);4、main 頭文件代碼如下:#include "a.h"#include "b.h"#include "c.h"void main()printf("* 生產者消費者模擬 n");printf(" n");printf("* 請輸入字符串 :n");sca

溫馨提示

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

評論

0/150

提交評論