完整版模拟PV操作同步机构,且用PV操作解决生产者——消费者问题_第1页
完整版模拟PV操作同步机构,且用PV操作解决生产者——消费者问题_第2页
完整版模拟PV操作同步机构,且用PV操作解决生产者——消费者问题_第3页
完整版模拟PV操作同步机构,且用PV操作解决生产者——消费者问题_第4页
完整版模拟PV操作同步机构,且用PV操作解决生产者——消费者问题_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验四:同步机构实验报告学院:专业班级:姓名:学号:一、实验内容:模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。二、实验目的:进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。我们把若干个进程都能进行访问和修改的那些变量称为公共变量。由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。一般说,同步机构是由若干条原语一一同步原语一一所组成。本实验要求学生模拟PV操作同步机构

2、的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。三、实验题目:模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。四、此次用到的数据结构知识如下:typedefstructPcbcharname10;进程名charstate10;/运行状态charreason10;/若阻塞,其原因intbreakp;/断点保护structPcb*next;阻塞时的顺序Pcb,*link;|进程名|状态等待原因断点后继进程进程控制块结构定义两个进程:linkp1;/生产者进程,linkc1;消费者进程。pc程序计数器和linkready;就绪队列,linkb_s1;si阻塞队列,linkb

3、_s2;s2阻塞队列。五、实验源代码:分为四个头文件。1、a.h头文件代码如下:#include<string.h>#include<ctype.h>#include<malloc.h>/*malloc()等*/#include<limits.h>/*INT_MAX等*/#include<stdio.h>/*EOF(=AZ或F6),NULL*/#include<stdlib.h>/*atoi()*/#include<io.h>/*eof()*/#include<math.h>/*floor(),ce

4、il(),abs()*/#include<process.h>/*exit()*/#include<iostream>usingnamespacestd;#include<time.h>#defineBUF10/缓存的大小#defineMAX20/最大可以输入的字符2、b.h头文件代码如下:/数据结构的定义和全局变量typedefstructPcb进程名运行状态若阻塞,其原因断点保护charname10;/charstate10;/charreason10;/intbreakp;/structPcb*next;/阻塞时的顺序Pcb,*link;ints1,s

5、2;/信号量linkp1;/生产者进程linkc1;/消费者进程charstrMAX;/输入的字符串charbufferBUF;/缓冲池intlen;/输入长度intsp=0;/string的指针intin=0;/生产者指针intout=0;/消费者指针chartemp;/供打印的临时产品charrec_pMAX;/生产记录intrp1=0;/生产记录指针charrec_cMAX;/消费记录intrp2=0;/消费记录指针linkready;/就绪队列linkb_s1;/s1阻塞队列linkb_s2;/s2阻塞队列intpc;/程序计数器intcount;/字符计数器intcon_cnt;/消

6、费计数器3、c.h头文件代码如下:voidinit();/初始化voidp(ints);/P操作voidv(ints);/V操作voidblock(ints);/阻塞函数voidwakeup(ints);/唤醒函数voidcontrol();/处理机调度voidprocessor。;/处理机执行voidprint();/打印函数voidinit()/初始化s1=BUF;s2=0;p1=(link)malloc(sizeof(Pcb);/建立新白结点,并初始化为生产者strcpy(p1->name,"Producer");strcpy(p1->state,&quo

7、t;Ready");strcpy(p1->reason,"Null");p1->breakp=0;p1->next=NULL;c1=(link)malloc(sizeof(Pcb);/建立新白结点,并初始化为消费者strcpy(c1->name,"Consumer");strcpy(c1->state,"Ready");strcpy(c1->reason,"Null");c1->breakp=0;c1->next=NULL;ready=p1;ready-&g

8、t;next=c1;/初始化为生产进程在前,消费进程在后c1->next=NULL;b_s1=NULL;b_s2=NULL;/阻塞进程为NULLpc=0;con_cnt=0;/消费计数器voidp(ints)if(s=1)/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

9、->breakp=pc;/保存断点voidv(ints)if(s=1)/v(s1)s1+;if(s1<=0)wakeup(1);/唤醒生产进程ready->breakp=pc;/保存断点else/v(s2)s2+;if(s2<=0)wakeup(2);/唤醒消费进程ready->breakp=pc;/保存断点)voidblock(ints)/阻塞函数的定义linkp;intnum1=0;intnum2=0;if(s=1)/生产进程strcpy(p1->state,"Block");/改变状态strcpy(p1->reason,&qu

10、ot;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生产进程阻塞了!n");ready->breakp=pc;/保存断点ready=ready->next;/在就绪队列中去掉,指向下一个num1+;)else/消费进程strcpy(c1->state,"Block");strcpy(c1->reason,"S2");p=b

11、_s2;while(p)num2+;p=p->next;/p的值为NULL,表示队尾)if(!b_s2)b_s2=c1;elsep=c1;ready->breakp=pc;/保存断点ready=ready->next;/在就绪队列中去掉,指向下一个c1->next=NULL;printf("t*c1消费进程阻塞了!n");num2+;)printf("t*阻塞的生产进程个数为:dn",num1);printf("t*阻塞的消费进程个数为:dn",num2);)voidwakeup(ints)/唤醒函数的定义li

12、nkp;linkq=ready;if(s=1)/唤醒b_s1队首进程,生产进程队列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*pl生产进程唤醒了!n");)else/唤醒b_s2队首进程,消费进程队列p=b_s2;b_s2=b_s2->next;/阻塞指针指向下一个阻塞

13、进程strcpy(p->state,"Ready");strcpy(p->reason,"Null");while(q->next)/插入就绪队列q=q->next;q->next=p;p->next=NULL;printf("t*c1消费进程唤醒了!n");)voidcontrol()/处理器调度程序intrd;intnum=0;linkp=ready;if(ready=NULL)/若无就绪进程,结束return;while(p)/统计就绪进程个数num+;p=p->next;/最终p变为N

14、ULLprintf("t*就绪进程个数为:dn",num);time_tt;srand(unsigned)time(&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");elsestrcpy(ready->state,"Run&qu

15、ot;);pc=ready->breakp;voidprocessor()/模拟处理器指令执行if(strcmp(ready->name,"Producer")=0)/当前进程为生产者switch(pc)case0:/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_prp

16、1;/放到缓冲区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;case4:/goto01printf("t*生产进程goto0操作n");pc=0;count-;/剩余字符个数减1printf("t*剩余字符count=%d个n",count);ready->breakp=pc;

17、/保存断点if(count<=0)/生产结束printf("t*生产者结束生产!n");strcpy(p1->state,"Stop");strcpy(p1->reason,"Null");ready->breakp=-1;ready=ready->next;/在就绪队列中去掉else/当前进程为消费者switch(pc)(case0:/p(s2)pc+;p(2);break;case 1: /getprintf("t*消费者取字符!n");temp=bufferout;out=(ou

18、t+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");/完成态c1->breakp=-1;return;pc+;ready->breakp=pc;

19、/保存断点break;case 4: /goto0printf("t*消费进程goto0操作n");pc=0;ready->breakp=pc;/保存断点voidprint()inti,j;printf("生产者消费者模拟n");printf("*模拟过程的字符串为:t");printf("%sn",&str);printf("*已生产:");for(j=0;j<=rp1;j+)printf("%c",rec_pj);printf("n*空缓存:

20、");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->state,p1->reason,p1->breakp);prin

21、tf("%st%st%stt%dn",c1->name,c1->state,c1->reason,c1->breakp);printf("n");printf("1.继续0.退出n");scanf("%d",&i);if(i=0)exit(0);4、main头文件代码如下:#include"a.h"#include"b.h"#include"c.h"voidmain()printf("*生产者消费者模拟n"

22、;);printf("n");printf("*请输入字符串:n");scanf("%s",str);/string数组存放将要产生的字符len=strlen(str);count=len;/输入字符的个数init();/初始化while(con_cnt<len)/消费完所有的字符为结束system("cls");/清屏操作printf("模拟指令流程n");control。;/处理器调度程序processor。;/模拟处理器指令执行print();/输出显示各个信息printf("n程序结束!n");就名_生产者生产愎拟指令流程不数为六、运行结果截图:生产群模拟过程的字符串为:已生产储空缓存:陋程名Proncei,ConsLinera者模拟abedef进程控制块的信息一长

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论