#include <iostream>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#define MAX 50
#define OK 1
#define ERROR 0
int empty;//全局变量
int mutex;
int sa;
int sb;
typedef struct process{
char name[10];
char pubsignal[10];
char prisignal1[10];
char prisignal2[10];
char style;//P或者C
struct process *next;
}process,*queueptr;
typedef struct{
queueptr front;
queueptr rear;
}linkqueue;
void Initqueue(linkqueue &Q){
Q.front=Q.rear=(queueptr)malloc(sizeof(process));
if (!Q.front) exit (OVERFLOW);
Q.front->next=NULL;
Q.front->name[0]=0;//赋初值
Q.front->prisignal1[0]=0;
Q.front->prisignal2[0]=0;
Q.front->pubsignal[0]=0;
Q.front->style=0;
return;
}
void Enqueue(linkqueue &Q,char a[],char b[],char c[],char d[],char e){
queueptr p;
p=(queueptr)malloc(sizeof(process));
if (!p) exit (OVERFLOW);
for (int i=0;i<10;i++)
{
p->name[i]=a[i];
}
for (int j=0;j<10;j++)
{
p->pubsignal[j]=b[j];
}
for (int x=0;x<10;x++)
{
p->prisignal1[x]=c[x];
}
for (int y=0;y<10;y++)
{
p->prisignal2[y]=d[y];
}
p->style=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return;
}
void Dequeue(linkqueue &Q){
if (Q.front==Q.rear) return;
queueptr p;
p=Q.front->next;
Q.front->next=p->next;
if (Q.rear==p) Q.rear=Q.front;
delete (p);
return;
}
void printprocess(linkqueue &Q)
{
queueptr p;
p=Q.front->next;
do{
printf("--------------------------------------------------------------------------------\n");
printf("进程名%s 互斥信号量%s 私有信号量%s 私有信号量%s 进程类型%c\n",p->name,p->pubsignal,p->prisignal1,p->prisignal2,p->style);
printf("--------------------------------------------------------------------------------\n");
p=p->next;
}while (p!=NULL);
}
void P(char a[],linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
if (strcmp("mutex",a)==0)
{
mutex--;
if (mutex<0)//进程挂起,到信号量mutex的队尾排队
{
//mutex=0;//强制置零,冒险?
printf("信号量mutex不足,<%s>到信号量mutex队尾排队\n",excutiveQ.front->next->name);
Enqueue(mutexQ,excutiveQ.front->next->name,excutiveQ.front->next->pubsignal,excutiveQ.front->next->prisignal1,excutiveQ.front->next->prisignal2,excutiveQ.front->next->style);
Dequeue(excutiveQ);
}
}
if (strcmp("empty",a)==0)
{
empty--;
if (empty<0)//进程挂起,到信号量empty的队尾排队
{
//empty=0;
printf("信号量empty不足,<%s>到信号量empty队尾排队\n",excutiveQ.front->next->name);
Enqueue(emptyQ,excutiveQ.front->next->name,excutiveQ.front->next->pubsignal,excutiveQ.front->next->prisignal1,excutiveQ.front->next->prisignal2,excutiveQ.front->next->style);
Dequeue(excutiveQ);
}
}
if (strcmp("sa",a)==0)
{
sa--;
if (sa<0)//进程挂起,到信号量sa的队尾排队
{
//sa=0;
printf("信号量sa不足,<%s>到信号量sa队尾排队\n",excutiveQ.front->next->name);
Enqueue(saQ,excutiveQ.front->next->name,excutiveQ.front->next->pubsignal,excutiveQ.front->next->prisignal1,excutiveQ.front->next->prisignal2,excutiveQ.front->next->style);
Dequeue(excutiveQ);
}
}
if (strcmp("sb",a)==0)
{
sb--;
if (sb<0)//进程挂起,到信号量sb的队尾排队
{
//sb=0;
printf("信号量sb不足,<%s>到信号量sb队尾排队\n",excutiveQ.front->next->name);
Enqueue(sbQ,excutiveQ.front->next->name,excutiveQ.front->next->pubsignal,excutiveQ.front->next->prisignal1,excutiveQ.front->next->prisignal2,excutiveQ.front->next->style);
Dequeue(excutiveQ);
}
}
}
void V(char a[],linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
if (strcmp("mutex",a)==0)
{
mutex++;
if (mutex>0)//进程唤醒,到执行进程队尾排队
{
if (mutexQ.front->next!=NULL){
printf("信号量mutex+1,mutex队列中的<%s>到执行进程队尾排队\n",mutexQ.front->next->name);
Enqueue(excutiveQ,mutexQ.front->next->name,mutexQ.front->next->pubsignal,mutexQ.front->next->prisignal1,mutexQ.front->next->prisignal2,mutexQ.front->next->style);
Dequeue(mutexQ);}
}
}
else if (strcmp("empty",a)==0)
{
empty++;
if (empty>0)//进程唤醒,到执行队尾排队
{
if (emptyQ.front->next!=NULL){
printf("信号量empty+1,empty队列中的<%s>到执行进程队尾排队\n",emptyQ.front->next->name);
Enqueue(excutiveQ,emptyQ.front->next->name,emptyQ.front->next->pubsignal,emptyQ.front->next->prisignal1,emptyQ.front->next->prisignal2,emptyQ.front->next->style);
Dequeue(emptyQ);}
}
}
else if (strcmp("sa",a)==0)
{
sa++;
if (sa>0)//进程唤醒,到执行队尾排队
{
if (saQ.front->next!=NULL){//队列不为空
printf("信号量sa+1,sa队列中的<%s>到执行进程队尾排队\n",saQ.front->next->name);
Enqueue(excutiveQ,saQ.front->next->name,saQ.front->next->pubsignal,saQ.front->next->prisignal1,saQ.front->next->prisignal2,saQ.front->next->style);
Dequeue(saQ);}
}
}
else if (strcmp("sb",a)==0)
{
sb++;
if (sb>0)//进程唤醒,到执行队尾排队
{
if (sbQ.front->next!=NULL){
printf("信号量sb+1,sb队列中的<%s>到执行进程队尾排队\n",mutexQ.front->next->name);
Enqueue(excutiveQ,sbQ.front->next->name,sbQ.front->next->pubsignal,sbQ.front->next->prisignal1,sbQ.front->next->prisignal2,sbQ.front->next->style);
Dequeue(sbQ);}
}
}
}
void excutiveproducer1(linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
while (1)
{
printf("-----------------现在执行的进程是<%s>-----------------\n",excutiveQ.front->next->name);
P("empty",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(empty)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (empty<0)
{ empty=0;
break; }
P("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (mutex<0) break;
if (empty>=0&&mutex>=0)
{
printf("-------------------------------生产%s-------------------------------\n",excutiveQ.front->next->prisignal2);
V("sa",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(sa)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
V("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
}
}
return;
}
void excutiveproducer2(linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
while (1)
{
printf("-----------------现在执行的进程是<%s>-----------------\n",excutiveQ.front->next->name);
P("empty",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(empty)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (empty<0)
{
empty=0;
break;}
P("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (mutex<0) break;
if (empty>=0&&mutex>=0)
{
printf("-------------------------------生产%s-------------------------------\n",excutiveQ.front->next->prisignal2);
V("sb",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(sb)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
V("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
}
}
return;
}
void excutiveconsumer1(linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
while (1)
{
printf("-----------------现在执行的进程是<%s>-----------------\n",excutiveQ.front->next->name);
P("sa",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(sa)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (sa<0)
{
sa=0;
break;}
P("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (mutex<0) break;
if (sa>=0&&mutex>=0)
{
printf("-------------------------------消费%s-------------------------------\n",excutiveQ.front->next->prisignal2);
V("empty",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(empty)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
V("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
}
}
return;
}
void excutiveconsumer2(linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
while (1)
{
printf("-----------------现在执行的进程是<%s>-----------------\n",excutiveQ.front->next->name);
P("sb",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(sb)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (sb<0)
{
sb=0;
break;}
P("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("P(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
if (mutex<0) break;
if (sb>=0&&mutex>=0)
{
printf("-------------------------------消费%s-------------------------------\n",excutiveQ.front->next->prisignal2);
V("empty",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(empty)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
V("mutex",excutiveQ,mutexQ,emptyQ,saQ,sbQ);
printf("V(mutex)之后,mutex=%d,empty=%d,sa=%d,sb=%d\n",mutex,empty,sa,sb);
}
}
return;
}
void excuteprocess(linkqueue &excutiveQ,linkqueue &mutexQ,linkqueue &emptyQ,linkqueue &saQ,linkqueue &sbQ)
{
if (strcmp(excutiveQ.front->next->name,"producer1")==0)//队列中第一个结点是空,去第二个结点来判断
{
excutiveproducer1(excutiveQ,mutexQ,emptyQ,saQ,sbQ);
}
else if (strcmp(excutiveQ.front->next->name,"producer2")==0)
{
excutiveproducer2(excutiveQ,mutexQ,emptyQ,saQ,sbQ);
}
else if (strcmp(excutiveQ.front->next->name,"consumer1")==0)
{
excutiveconsumer1(excutiveQ,mutexQ,emptyQ,saQ,sbQ);
}
else if (strcmp(excutiveQ.front->next->name,"consumer2")==0)
{
excutiveconsumer2(excutiveQ,mutexQ,emptyQ,saQ,sbQ);
}
}
void main()
{
empty=2;
mutex=2;
sa=0;
sb=0;
linkqueue excutiveQ;
linkqueue emptyQ;
linkqueue saQ;
linkqueue sbQ;
linkqueue mutexQ;
Initqueue(excutiveQ);//就绪队列
Initqueue(emptyQ);//信号量empty的等待队列
Initqueue(saQ);//信号量sa的等待队列
Initqueue(sbQ);//信号量sb的等待队列
Initqueue(mutexQ);//信号量mutex的等待队列
Enqueue(excutiveQ,"producer1","mutex","empty","sa",'P');
Enqueue(excutiveQ,"producer2","mutex","empty","sb",'P');
Enqueue(excutiveQ,"consumer1","mutex","empty","sa",'C');
Enqueue(excutiveQ,"consumer2","mutex","empty","sb",'C');
//excutiveQ.front=excutiveQ.front->next;//去掉队列中的第一个结点
printf("--------------------------------------------------------------------------------\n");
int flag;
do
{
printf("1.进程信息 2.开始 3.结束\n");
scanf("%d",&flag);
if (flag==1)
{
printprocess(excutiveQ);
}
if (flag==2)//执行进程
{
printf("---------->初始信号量mutex=%d,empty=%d,sa=%d,sb=%d<------------\n",mutex,empty,sa,sb);
excuteprocess(excutiveQ,mutexQ,emptyQ,saQ,sbQ);
}
}while (flag!=3);
}