进程同步C 的实现实验一进程同步
一、实验目的
了解生产者与消费者在实现进程同步过程中的解决方案。
二、实验步骤
数据结构:
每个进程用一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。
系统开辟了一个缓冲区,大小由buffersize指定。
程序中有三个链队列,一个链表。一个就绪队列(ready),两个等待队列:生产者等待队列(producer)、消费者等待队列(consumer);一个链表(over):用于收集已经运行结束的进程。
...
实验一进程同步
一、实验目的
了解生产者与消费者在实现进程同步过程中的解决
。
二、实验步骤
数据结构:
每个进程用一个进程控制块(PCB)
示。进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。
系统开辟了一个缓冲区,大小由buffersize指定。
程序中有三个链队列,一个链表。一个就绪队列(ready),两个等待队列:生产者等待队列(producer)、消费者等待队列(consumer);一个链表(over):用于收集已经运行结束的进程。
本程序通过函数模拟信号量的原子操作。
算法的文字描述:
①由用户指定要产生的进程及其类别,进入就绪队列。
②调度程序从就绪队列中提取一个就绪进程运行。如果申请的资源不存在则进入相应的等待队列,调度程序调度就绪队列中的下一个进程。进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就绪队列。运行结束的进程进入over链表。重复这一过程直至就绪队列为空。
③程序询问是否要继续?如果继续转开始执行,否则退出程序。
源程序:
#include
using namespace std;
int const buffersize = 5;
/* 定义进程控制块PCB */
struct PCB
{
int flag; //flag=1 denote producer;flag=2 denote consumer;
int numlabel;
char product;
char state;
struct PCB* processlink;
}*exe=0,*over=0;
PCB * readyhead = 0, * readytail = 0;
PCB * consumerhead = 0,* consumertail = 0; PCB * producerhead = 0,* producertail = 0;
int productnum=0; //产品数量int processnum=0; //进程数int full=0,empty=buffersize; // semaphore
char buffer[buffersize]; //缓冲区
int bufferpoint=0; //缓冲区指针
void linkqueue( PCB* process, PCB* & tail ); PCB* getp(PCB* head, PCB* & tail);
int hasElement(PCB* pro);
void display(PCB* p);
void linklist(PCB* p,PCB* listhead);
void freelink(PCB* linkhead);
int processproc();
int waitfull();
int waitempty();
void signalempty();
void signalfull();
void producerrun();
void comsuerrun();
int main()
{
char begin;
int element;
cout<<"你想开始程序吗?(y/n)";
cin>>begin;
producerhead = new PCB;
if( !producerhead ) return 1;
producertail = producerhead;
producerhead->processlink = 0;
producerhead->flag = 1;
producerhead->numlabel = processnum;
consumerhead = new PCB;
if( !consumerhead ) return 1;
consumertail = consumerhead;
consumerhead->processlink = 0;
consumerhead->flag = 2;
consumerhead->numlabel = processnum;
readyhead = new PCB;
if( !readyhead ) return 1;
readytail = readyhead;
readyhead->processlink = 0;
readyhead->flag = 3;
readyhead->numlabel = processnum;
over = new PCB;
if ( !over ) return 1;
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 )
comsuerrun( );
else
comsuerrun( );
element = hasElement(readyhead);
}
cout<<"就绪队列中无进程"<>begin;
}
cout<<"\n 进程模拟完成."<processlink )
{
cursor = cursor->processlink;
}
cursor->processlink = p;
}
void freelink(PCB* linkhead)
{
PCB* p;
while( linkhead )
{
p = linkhead;
linkhead = linkhead->processlink;
delete(p);
}
}
void linkqueue( 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
return 0;
return p;
}
int processproc( )
{
int flag,num;
char ch;
PCB* p = 0;
cout<<"\n 请输入希望产生的进程个数:";
cin>>num;
for(int i=0;i>flag;
p = new PCB;
if( !p )
{
cout<<"内存分配失败!"<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);
}
return 1;
}
int waitempty()
{
if(empty<=0 )
{
printf("进程%d:缓冲区存数,缓冲区满,该进程进入生产者等待队列\n",exe->numlabel);
linkqueue( exe, producertail );
return 0;
}
else
{
empty--;
return 1;
}
}
int waitfull()
{
if(full<=0)
{
printf("进程%d:缓冲区取数,缓冲区空,该进程进入消费者等待队列\n",exe->numlabel);
linkqueue( exe, consumertail );
return 0;
}
else
{
full--;
return 1;
}
}
void signalempty( )
{
PCB* p;
if( hasElement(producerhead) )
{
p = getp( producerhead,producertail );
linkqueue( p, readytail );
printf("等待中的生产者进程进入就绪队列,它的进程号是%d\n",p->numlabel);
}
empty++;
}
void signalfull( )
{
PCB* p;
if( hasElement(consumerhead) )
{
p = getp(consumerhead,consumertail);
linkqueue(p,readytail);
printf("等待中的消费者进程进入就绪队列,它的进程号是%d\n",p->numlabel);
}
full++;
}
void producerrun( )
{
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);
}
void comsuerrun( )
{
if(!waitfull())
return;
printf("进程%d开始从缓冲区取数\n",exe->numlabel);
exe->product = buffer[bufferpoint-1];
bufferpoint--;
printf("进程%d从缓冲区取数操作结束,取数是%c\n",exe->numlabel,exe->product);
signalempty();
linklist( exe, over );
}
void display(PCB* p)
{
p=p->processlink;
while( p )
{
p->flag==1? printf("生产者进程"):printf("消费者进程");
printf("%d\n",p->numlabel);
p = p->processlink;
}
}
int hasElement(PCB* pro)
{
if( !pro->processlink )
return 0;
else
return 1;
}
三.实验结果
输入测试数据,产生不同结果的原因。
四.实验讨论
收获体会及对该题解的改进意见和见解。
本文档为【进程同步C 的实现】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。