#include <stdio.h>
#include <malloc.h>//引入动态分配内存函数
#define buffersize 5//假设有5个缓冲区
int processnum=0;//初始化产品数量
struct pcb /* 定义进程控制块PCB /
{
int flag;//定义int型结构体成员
int numlabel;
char product;// 定义char型结构体成员
char state;
struct pcb processlink; //定义char型指针
}exe=NULL,over=NULL;//指针初始值赋值为空
typedef struct pcb PCB;
PCB readyhead=NULL, readytail=NULL;
PCB* consumerhead=NULL,* consumertail=NULL;
PCB* producerhead=NULL,* producertail=NULL;
int productnum=0;//产品数量
int full=0,empty=buffersize;//信号量
char buffer[buffersize];//缓冲区
int bufferpoint=0;//缓冲区指针
void linklist(PCB* p,PCB* listhead)//创建就绪队列
{
PCB* cursor=listhead;
while(cursor->processlink!=NULL){//运用while循环预测指针是否为空
cursor=cursor->processlink;
}
cursor->processlink=p;
}
void freelink(PCB* linkhead)
{
PCB* p;
while(linkhead!=NULL)
{
p=linkhead;
linkhead=linkhead->processlink;
free§;//释放指针
}
}
void linkqueue(PCB* process,PCB** tail)//初始化队列
{
if((tail)!=NULL)//用if语句探测队尾是否为空
{
(tail)->processlink=process;
(tail)=process;//队尾指针赋值为process
}
else {printf(“队列未初始化!”);}//输出队列未初始化
}
PCB getq(PCB head,PCB* tail) //调用指向指针的指针指向头指针与尾指针
{
PCB* p;//生命pcb指针
p=head->processlink;
if(p!=NULL)
{
head->processlink=p->processlink;
p->processlink=NULL;
if( head->processlink NULL ) (tail)=head;//指针尾赋值给头部
}
else return NULL;
return p;
}
bool processproc()//初始化进程
{
int i,f,num;
char ch;
PCB p=NULL;
PCB** p1=NULL;
printf("\n请输入希望产生的进程个数:"); //输入进程数
scanf("%d",&num);
getchar();//调用getchar函数接收字符
for(i=0;i<num;i++)
{
printf("\n请输入您要产生的进程:输入1为生产者进程;输入2为消费者进程\n");
scanf("%d",&f);
getchar();
p=(PCB*)malloc(sizeof(PCB)) ;
if( !p) {printf(“内存分配失败”); return false; }
p->flag=f;
processnum++;
p->numlabel=processnum;
p->state=‘w’;
p->processlink=NULL;
if(p->flag1)
{ printf(“您要产生的进程是生产者,它是第%d个进程。请您输入您要该进程产生的字符:\n”,processnum);
scanf("%c",&ch);
getchar();
p->product=ch;
productnum++;//变量自增
printf(“您要该进程产生的字符是%c \n”,p->product);
}
else { printf(“您要产生的进程是消费者,它是第%d个进程。\n”,p->numlabel);}
linkqueue(p,&readytail);
}
return true;
}
bool hasElement(PCB* pro)//判断队列中是否有进程存在
{
if(pro->processlinkNULL) return false;
else return true;
}
bool waitempty()//判断生产者等待队列是否为空
{
if(empty<=0)
{
printf(“进程%d:缓冲区存数,缓冲区满,该进程进入生产者等待队列\n”,exe->numlabel);
linkqueue(exe,&producertail);
return false;
}
else{ empty–; return true; }
}
void signalempty()//唤醒生产者进程
{
PCB* p;
if(hasElement(producerhead)){
p=getq(producerhead,&producertail);
linkqueue(p,&readytail);
printf(“等待中的生产者进程进入就绪队列,它的进程号是%d\n”,p->numlabel);
}
empty++;
}
bool waitfull()//判断消费者等待队列是否为满
{
if(full<=0)
{
printf(“进程%d:缓冲区取数,缓冲区空,该进程进入消费者等待队列\n”,exe->numlabel);
linkqueue(exe,&consumertail);
return false;
}
else{ full–; return true;}
}
void signalfull()//唤醒消费者进程
{
PCB* p;
if(hasElement(consumerhead)){
p=getq(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!=NULL){
printf(“进程%d,它是一个”,p->numlabel);
p->flag1? printf(“生产者\n”):printf(“消费者\n”);
p=p->processlink;
}
}
void main()
{
char terminate;//创建char型字符
bool element;//创建布尔型字符
printf(“你想开始程序吗?(y/n)”);//输出提示语言
scanf("%c",&terminate);//输入字符
getchar();//使用getchar函数接收字符
readyhead=(PCB*)malloc(sizeof(PCB));//初始化队列
if(readyheadNULL) return;//如果输入为空,则返回空值
readytail=readyhead;//将变量赋值给另一个变量
readyhead->flag=3;//将标志位赋值为3
readyhead->numlabel=processnum;
readyhead->state=‘w’;//赋值字符为’w’
readyhead->processlink=NULL;//赋值为空
consumerhead=(PCB*)malloc(sizeof(PCB));//调用动态分配空间函数和字符测量函数
if(consumerheadNULL) return;
consumertail=consumerhead;
consumerhead->processlink=NULL;
consumerhead->flag=4;//测量到标志位为4
consumerhead->numlabel=processnum;
consumerhead->state=‘w’;
consumerhead->processlink=NULL;
producerhead=(PCB*)malloc(sizeof(PCB));
if(producerheadNULL) return;
producertail=producerhead;
producerhead->processlink=NULL;
producerhead->flag=5;
producerhead->numlabel=processnum;
producerhead->state=‘w’;
producerhead->processlink=NULL;
over=(PCB*)malloc(sizeof(PCB));
if(overNULL) return;
over->processlink=NULL;
while(terminate==‘y’)
{
if(!processproc()) break;
element=hasElement(readyhead);
while(element){
exe=getq(readyhead,&readytail);
printf(“进程%d申请运行,它是一个”,exe->numlabel);
exe->flag1? printf(“生产者\n”):printf(“消费者\n”);
if(exe->flag1) producerrun();
else comsuerrun();
element=hasElement(readyhead);
}
printf(“就绪队列没有进程\n”);
if(hasElement(consumerhead))
{
printf(“消费者等待队列中有进程:\n”);
display(consumerhead);
}
else { printf(“消费者等待队列中没有进程\n”); }
if(hasElement(producerhead))
{ printf(“生产者等待队列中有进程:\n”);
display(producerhead);
}
else {
printf(“生产者等待队列中没有进程\n”);
}
printf(“你想继续吗?(press ‘y’ for on)”);
scanf("%c",&terminate);
getchar();
}
printf("\n\n 进程模拟完成.\n");
freelink(over);//释放空间
over=NULL;
freelink(readyhead);
readyhead=NULL;
readytail=NULL;
freelink(consumerhead);
consumerhead=NULL;
consumertail=NULL;
freelink(producerhead);
producerhead=NULL;
producertail=NULL;
getchar();
}
输出结果:
c实现进程的同步与互斥
最新推荐文章于 2025-02-10 16:48:14 发布