实验一进程同步.docx
《实验一进程同步.docx》由会员分享,可在线阅读,更多相关《实验一进程同步.docx(11页珍藏版)》请在冰豆网上搜索。
实验一进程同步
试验报告要求
一.实验题目
二.实验目的
三.实验记录
四.实验结果
输入测试数据,分析产生不同结果的原因。
五.实验讨论
收获体会及对该题解的改进意见和见解
实验一进程同步
一、实验目的
了解生产者与消费者在实现进程同步过程中的解决方案。
二、实验步骤
数据结构:
每个进程用一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。
系统开辟了一个缓冲区,大小由buffersize指定。
程序中有三个链队列,一个链表。
一个就绪队列(ready),两个等待队列:
生产者等待队列(producer)、消费者等待队列(consumer);一个链表(over):
用于收集已经运行结束的进程。
本程序通过函数模拟信号量的原子操作。
算法的文字描述:
①由用户指定要产生的进程及其类别,进入就绪队列。
②调度程序从就绪队列中提取一个就绪进程运行。
如果申请的资源不存在则进入相应的等待队列,调度程序调度就绪队列中的下一个进程。
进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就绪队列。
运行结束的进程进入over链表。
重复这一过程直至就绪队列为空。
③程序询问是否要继续?
如果继续转开始执行,否则退出程序。
源程序:
#include
usingnamespacestd;
intconstbuffersize=5;
/*定义进程控制块PCB*/
structPCB
{
intflag;//flag=1denoteproducer;flag=2denoteconsumer;
intnumlabel;
charproduct;
charstate;
structPCB*processlink;
}*exe=0,*over=0;
PCB*readyhead=0,*readytail=0;
PCB*consumerhead=0,*consumertail=0;
PCB*producerhead=0,*producertail=0;
intproductnum=0;//产品数量
intprocessnum=0;//进程数
intfull=0,empty=buffersize;//semaphore
charbuffer[buffersize];//缓冲区
intbufferpoint=0;//缓冲区指针
voidlinkqueue(PCB*process,PCB*&tail);
PCB*getp(PCB*head,PCB*&tail);
inthasElement(PCB*pro);
voiddisplay(PCB*p);
voidlinklist(PCB*p,PCB*listhead);
voidfreelink(PCB*linkhead);
intprocessproc();
intwaitfull();
intwaitempty();
voidsignalempty();
voidsignalfull();
voidproducerrun();
voidcomsuerrun();
intmain()
{
charbegin;
intelement;
cout<<"你想开始程序吗?
(y/n)";
cin>>begin;
producerhead=newPCB;
if(!
producerhead)return1;
producertail=producerhead;
producerhead->processlink=0;
producerhead->flag=1;
producerhead->numlabel=processnum;
consumerhead=newPCB;
if(!
consumerhead)return1;
consumertail=consumerhead;
consumerhead->processlink=0;
consumerhead->flag=2;
consumerhead->numlabel=processnum;
readyhead=newPCB;
if(!
readyhead)return1;
readytail=readyhead;
readyhead->processlink=0;
readyhead->flag=3;
readyhead->numlabel=processnum;
over=newPCB;
if(!
over)return1;
over->processlink=0;
while(begin=='y')
{
if(!
processproc())break;
element=hasElement(readyhead);
while(element)
{
exe=getp(readyhead,readytail);
printf("进程%d申请运行,它是一个",exe->numlabel);
exe->flag==1?
printf("生产者\n"):
printf("消费者\n");
if(exe->flag==1)
producerrun();
else
comsuerrun();
element=hasElement(readyhead);
}
cout<<"就绪队列中无进程"<if(hasElement(consumerhead))
{
cout<<"消费者等待队列中有进程:
"<display(consumerhead);
}
else
{
cout<<"消费者等待队列中已无进程!
"<}
if(hasElement(producerhead))
{
cout<<"生产者等待队列中有进程:
"<display(producerhead);
}
else
{
cout<<"生产者等待队列中已无进程!
"<}
cout<<"\n你想继续吗?
(press/'y/'for/'n/')";
cin>>begin;
}
cout<<"\n进程模拟完成."<freelink(over);
over=0;
freelink(readyhead);
readyhead=0;
readytail=0;
freelink(consumerhead);
consumerhead=0;
consumertail=0;
freelink(producerhead);
producerhead=0;
producertail=0;
return0;
}
voidlinklist(PCB*p,PCB*listhead)
{
PCB*cursor=listhead;
while(cursor->processlink)
{
cursor=cursor->processlink;
}
cursor->processlink=p;
}
voidfreelink(PCB*linkhead)
{
PCB*p;
while(linkhead)
{
p=linkhead;
linkhead=linkhead->processlink;
delete(p);
}
}
voidlinkqueue(PCB*process,PCB*&tail)
{
if(tail)
{
tail->processlink=process;
tail=process;
}
else
{
cout<<"队列未初始化!
";
exit
(1);
}
}
PCB*getp(PCB*head,PCB*&tail)
{
PCB*p;
p=head->processlink;
if(p)
{
head->processlink=p->processlink;
p->processlink=0;
if(!
head->processlink)
tail=head;
}
else
return0;
returnp;
}
intprocessproc()
{
intflag,num;
charch;
PCB*p=0;
cout<<"\n请输入希望产生的进程个数:
";
cin>>num;
for(inti=0;i{
cout<<"\n请输入您要产生的进程:
输入1为生产者进程;输入2为消费者进程\n";
cin>>flag;
p=newPCB;
if(!
p)
{
cout<<"内存分配失败!
"<return0;
}
p->flag=flag;
processnum++;
p->numlabel=processnum;
p->processlink=0;
if(p->flag==1)
{
printf("您要产生的是生产者进程,它是第%d个进程,请输入您要该进程产生的字符:
\n",processnum);
cin>>ch;
p->product=ch;
productnum++;
printf("您要该进程产生的字符是%c\n",p->product);
}
else
{
printf("您要产生的是消费者进程,它是第%d个进程。
\n",p->numlabel);
}
linkqueue(p,readytail);
}
return1;
}
intwaitempty()
{
if(empty<=0)
{
printf("进程%d:
缓冲区存数,缓冲区满,该进程进入生产者等待队列\n",exe->numlabel);
linkqueue(exe,producertail);
return0;
}
else
{
empty--;
return1;
}
}
intwaitfull()
{
if(full<=0)
{
printf("进程%d:
缓冲区取数,缓冲区空,该进程进入消费者等待队列\n",exe->numlabel);
linkqueue(exe,consumertail);
return0;
}
else
{
full--;
return1;
}
}
voidsignalempty()
{
PCB*p;
if(hasElement(producerhead))
{
p=getp(producerhead,producertail);
linkqueue(p,readytail);
printf("等待中的生产者进程进入就绪队列,它的进程号是%d\n",p->numlabel);
}
empty++;
}
voidsignalfull()
{
}
voidproducerrun()
{
if(!
waitempty())
return;
printf("进程%d开始向缓冲区存数%c\n",exe->numlabel,exe->product);
buffer[bufferpoint]=exe->product;
bufferpoint++;
printf("进程%d向缓冲区存数操作结束\n",exe->numlabel);
signalfull();
linklist(exe,over);
}
voidcomsuerrun()
{
}
voiddisplay(PCB*p)
{
p=p->processlink;
while(p)
{
p->flag==1?
printf("生产者进程"):
printf("消费者进程");
printf("%d\n",p->numlabel);
p=p->processlink;
}
}
inthasElement(PCB*pro)
{
if(!
pro->processlink)
return0;
else
return1;
}
三.实验结果
输入测试数据,分析产生不同结果的原因。
四.实验讨论
收获体会及对该题解的改进意见和见解。