模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc

上传人:b****9 文档编号:158492 上传时间:2022-10-04 格式:DOC 页数:16 大小:287KB
下载 相关 举报
模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc_第1页
第1页 / 共16页
模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc_第2页
第2页 / 共16页
模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc_第3页
第3页 / 共16页
模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc_第4页
第4页 / 共16页
模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc

《模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc》由会员分享,可在线阅读,更多相关《模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc(16页珍藏版)》请在冰豆网上搜索。

模拟PV操作同步机构-且用PV操作解决生产者——消费者问题.doc

实验四:

同步机构实验报告

学院:

专业班级:

姓名:

学号:

一、实验内容:

模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

二、实验目的:

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实验要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

三、实验题目:

模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。

四、此次用到的数据结构知识如下:

typedefstructPcb{

charname[10];//进程名

charstate[10];//运行状态

charreason[10];//若阻塞,其原因

intbreakp;//断点保护

structPcb*next;//阻塞时的顺序

进程名

状态

等待原因

断点

后继进程

}Pcb,*link;

进程控制块结构

定义两个进程:

linkp1;//生产者进程,linkc1;//消费者进程。

pc程序计数器和

linkready;就绪队列,linkb_s1;s1阻塞队列,linkb_s2;s2阻塞队列。

五、实验源代码:

分为四个头文件。

1、a.h头文件代码如下:

#include

#include

#include/*malloc()等*/

#include/*INT_MAX等*/

#include/*EOF(=^Z或F6),NULL*/

#include/*atoi()*/

#include/*eof()*/

#include/*floor(),ceil(),abs()*/

#include/*exit()*/

#include

usingnamespacestd;

#include

#defineBUF10//缓存的大小

#defineMAX20//最大可以输入的字符

2、b.h头文件代码如下:

//数据结构的定义和全局变量

typedefstructPcb{

charname[10];//进程名

charstate[10];//运行状态

charreason[10];//若阻塞,其原因

intbreakp;//断点保护

structPcb*next;//阻塞时的顺序

}Pcb,*link;

ints1,s2;//信号量

linkp1;//生产者进程

linkc1;//消费者进程

charstr[MAX];//输入的字符串

charbuffer[BUF];//缓冲池

intlen;//输入长度

intsp=0;//string的指针

intin=0;//生产者指针

intout=0;//消费者指针

chartemp;//供打印的临时产品

charrec_p[MAX];//生产记录

intrp1=0;//生产记录指针

charrec_c[MAX];//消费记录

intrp2=0;//消费记录指针

linkready;//就绪队列

linkb_s1;//s1阻塞队列

linkb_s2;//s2阻塞队列

intpc;//程序计数器

intcount;//字符计数器

intcon_cnt;//消费计数器

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,"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->next=c1;//初始化为生产进程在前,消费进程在后

c1->next=NULL;

b_s1=NULL;

b_s2=NULL;//阻塞进程为NULL

pc=0;

con_cnt=0;//消费计数器

}

voidp(ints){

if(s==1){//p(s1)

s1--;

if(s1<0)

block

(1);//阻塞当前生产进程

else{

printf("\t*s1信号申请成功!

\n");

ready->breakp=pc;//保存断点

}

}

else{//p(s2)

s2--;

if(s2<0)

block

(2);//阻塞当前消费进程

else{

printf("\t*s2信号申请成功!

\n");

ready->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,"S1");//说明原因

p=b_s1;

while(p){

num1++;

p=p->next;//p的值为NULL,表示队尾

}

if(!

b_s1)

b_s1=p1;

else

p=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;

else

p=c1;

ready->breakp=pc;//保存断点

ready=ready->next;//在就绪队列中去掉,指向下一个

c1->next=NULL;

printf("\t*c1消费进程阻塞了!

\n");

num2++;

}

printf("\t*阻塞的生产进程个数为:

%d\n",num1);

printf("\t*阻塞的消费进程个数为:

%d\n",num2);

}

voidwakeup(ints){//唤醒函数的定义

linkp;

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*p1生产进程唤醒了!

\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->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变为NULL

}

printf("\t*就绪进程个数为:

%d\n",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");

}

else

strcpy(ready->s

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1