模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題_第1頁
模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題_第2頁
模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題_第3頁
模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題_第4頁
模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者——消費者問題_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

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

2、求學(xué)生模擬 PV操作同步機構(gòu)的實現(xiàn),模擬進程的并發(fā)執(zhí)行,了解進程并發(fā)執(zhí)行時同步機構(gòu)的作用三、實驗題目:模擬PV操作同步機構(gòu),且用PV操作解決生產(chǎn)者一一消費者問題。四、此次用到的數(shù)據(jù)結(jié)構(gòu)知識如下:typedef struct Pcbchar name10;進程名char state10;運行狀態(tài)char reaso n 10;/若阻塞,其原因int breakp;/斷點保護Pcb,*li nk;struct Pcb *n ext;/阻塞時的順序進程名狀態(tài) 等待原因斷點 后繼進程進程控制塊結(jié)構(gòu)定義兩個進程:link p1;生產(chǎn)者進程,link c1;消費者進程。pc程序計數(shù)器和 link read

3、y;就緒隊列,link b_s1; si阻塞隊列,link b_s2; s2阻塞隊列。五、實驗源代碼:分為四個頭文件。1 、a.h 頭文件代碼如下:#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#i nclude<stdio.h> /* EOF(=AZ #include<stdlib.h> /* atoi() */或 F6),NULL */#include<io

4、.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)的定義和全局變量進程名運行狀態(tài) 若阻塞,其原因 斷點保護typedef struct Pcbchar name10;

5、/char state10; / 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

6、;/ 生產(chǎn)記錄指針 char rec_cMAX;/ 消費記錄 int rp2=0;/ 消費記錄指針 link ready; / 就緒隊列 link b_s1; /s1 阻塞隊列 link 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)度

7、void processor();/處理機執(zhí)行void print(); /打印函數(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);/建立

8、新的結(jié)點 , 并初始化為消費者strcpy(c1->name,"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

9、(s=1) /p(s1) s1-; if(s1<0)block(1); / 阻塞當前生產(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->

10、;breakp=pc; / 保存斷點 else /v(s2)s2+;if(s2<=0)wakeup(2);/ 喚醒消費進程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(!

11、b_s1)b_s1=p1;elsep=p1;p1->next=NULL;printf("t* p1 生產(chǎn)進程阻塞了 !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=c

12、1;elsep=c1;ready->breakp=pc; / 保存斷點 ready=ready->next;/ 在就緒隊列中去掉 , 指向下一個 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)進程隊

13、列p=b_s1;b_s1=b_s1->next;/ 阻塞指針指向下一個阻塞進程 strcpy(p->state,"Ready");strcpy(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,"Read

14、y"); strcpy(p->reason,"Null");while(q->next)/ 插入就緒隊列 q=q->next;q->next=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)?NULL printf

15、("t* 就緒進程個數(shù)為 :%dn",num);time_t t;srand(unsigned) time(&t);rd=rand()%num;/ 隨機函數(shù)產(chǎn)生隨機數(shù)if(rd=1)p=ready;ready=ready->next;ready->next=p;p->next=NULL;strcpy(ready->state,"Run");strcpy(ready->next->state,"Ready");elsestrcpy(ready->state,"Run"

16、);pc=ready->breakp;void processor() / 模擬處理器指令執(zhí)行if(strcmp(ready->name,"Producer")=0) /當前進程為生產(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

17、=rec_prp1; / 放到緩沖區(qū)printf("t* %c 字符成功入駐空緩存 !n",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* 生產(chǎn)進程 goto 0 操作 n");pc=0;count-; /剩余字符個數(shù)減 1printf("t*剩余字符 count=%d個n&quo

18、t;,count);ready->breakp=pc; / 保存斷點if(count<=0) / 生產(chǎn)結(jié)束printf("t* 生產(chǎn)者結(jié)束生產(chǎn) !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(&quo

19、t;t* 消費者取字符 !n");temp=bufferout;out=(out+1)%BUF;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");

20、/ 完成態(tài) c1->breakp=-1;return;pc+; ready->breakp=pc; / 保存斷點 break;case 4: /goto0 printf("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) :&quo

21、t;);for(j=0;j<=rp1;j+) printf("%c",rec_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ài)t等待原因t斷點n");print

22、f("%st%st%stt%dnn",p1->name,p1->state,p1->reason,p1->b reakp);printf("%st%st%stt%dn",c1->name,c1->state,c1->reason,c1->breakp);printf(" printf("1. 繼續(xù) 0. 退出 n"); scanf("%d",&i);if(i=0)exit(0);4、main 頭文件代碼如下:n"#include "

23、;a.h"#include "b.h"#include "c.h"void main()printf("* 生產(chǎn)者消費者模擬 n");printf(" n");printf("* 請輸入字符串 :n");scanf("%s",str); /string 數(shù)組存放將要產(chǎn)生的字符 len=strlen(str);count=len; / 輸入字符的個數(shù)init(); / 初始化while(con_cnt<len) / 消費完所有的字符為結(jié)束system("cls"); / 清屏操作printf(" 模擬指令流程n");control(); / processor(); / print(); /處理器調(diào)度程序 模擬處理器指令執(zhí)行 輸出顯示各個信息printf(&

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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

提交評論