📄 wros2new.cpp
字号:
// MyOSnew.cpp : Defines the entry point for the console application.
//
//生产者--消费者问题
#include "stdafx.h"
#include <stdio.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
#define NIL -1
#define MAX 6
#define Length 3//缓冲池长度
struct tagpcb /* 进程控制块的结构 */
{
int id; /* 进程内部标识符 */
char status; /* 进程状态 */
int priority; /* 进程初始优先数 */
int nptr; /* 进程队列指针 */
char save; /* 断点保存 */
}pcb[MAX];
struct tagsem /* 信号量的结构 */
{
int value; /* 信号量的值 */
int L; /* 进程链表指针 */
}sem[2];
int addr,run,m,k[MAX],jj[MAX];
/* addr为当前进程程序的执行地址;run为执行态进程的内部标识符;m为单缓冲区 */
int in,out,buffer[Length];//in是缓冲池输入指针,out是缓冲池输出指针,buffer[3]是缓冲池
void init(); /* 初始化模块 */
int scheduler();
//生产者进程
int processA();
int processB();
int processC();
//消费者进程
int processD();
int processE();
int processF();
void block(int *L);
void wakeup(int *L);
main()
{
int k,i,s;
char n[MAX];
printf("按优先级从大到小的顺序输入%d个进程的名称 :\n",MAX);
goto l1;
l2:printf("错误! 请重新输入 :\n");
l1:gets(n);
for(i=0;i<MAX;i++)
{if(!(isalpha(n[i])))goto l2;
n[i]=(n[i]>='a'&&n[i]<='z')?(n[i]-32):n[i];
}
for(i=0;i<MAX;i++)
switch(n[i])
{
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':break;
default: goto l2;
}
for(i=0;i<MAX-1;i++)
for(k=i+1;k<MAX;k++)
if(n[i]==n[k])goto l2;
for(i=0;i<MAX;i++)
switch(n[i])
{case 'A':jj[i]=0;break;
case 'B':jj[i]=1;break;
case 'C':jj[i]=2;break;
case 'D':jj[i]=3;break;
case 'E':jj[i]=4;break;
case 'F':jj[i]=5;break;
}
init();
for(s=0;s<2;s++)
printf("s%d.value=%d,s%d.L=NIL\n",s,sem[s].value,s);
printf("进程A:pcb1:pcb[%d], 进程B:pcb2:pcb[%d], 进程C:pcb3:pcb[%d]\n",pcb[0].id,pcb[1].id,pcb[2].id);
printf("进程D:pcb4:pcb[%d], 进程E:pcb5:pcb[%d], 进程F:pcb6:pcb[%d]\n",pcb[3].id,pcb[4].id,pcb[5].id);
printf("各进程优先级: A=%d,B=%d,C=%d, D=%d,E=%d,F=%d\n",
pcb[0].priority,pcb[1].priority,pcb[2].priority,pcb[3].priority,pcb[4].priority,pcb[5].priority);
for( ; ; )
{ printf("\n进程运行状态:A '%c' B '%c' C '%c' ",pcb[0].status,pcb[1].status,pcb[2].status);
printf("D '%c' E '%c' F '%c'\n",pcb[3].status,pcb[4].status,pcb[5].status);
if(scheduler() != NIL)
continue;
else
{
printf("\n进程运行状态:A '%c' B '%c' C '%c' ",pcb[0].status,pcb[1].status,pcb[2].status);
printf("D '%c' E '%c' F '%c'\n",pcb[3].status,pcb[4].status,pcb[5].status);
break;
}
} //end of for
printf("所有进程全部完成,系统停止。\n");
printf(" * * * * * 结束 * * * * *\n");
return 0;
}
void init()
{
int j;
for(j=0;j<MAX;j++) /* 进程控制块初始化 */
{
pcb[j].id=j;
pcb[j].status='R';
pcb[j].nptr=NIL;
pcb[j].save='F';
}
for(j=0;j<MAX;j++) /* 根据要求设置初始优先数 */
pcb[jj[j]].priority=j+1;
sem[0].value=Length;sem[0].L=NIL; /* 信号量初始化 */
sem[1].value=0;sem[1].L=NIL;
k[0]=k[1]=k[2]=4;k[3]=k[4]=k[5]=4; /* 设置循环次数 */
//m=0;
buffer[0]=buffer[1]=buffer[2]=0; /* 缓冲区清零 */
}
int wait(int i)
{
// s->value=s->value-1;
sem[i].value=sem[i].value-1;
printf("wait 信号量sem[%d],...sem[%d].value=%d\n",i,i,sem[i].value);
// printf("s->value=%d\n",s->value);
if(sem[i].value<0) //wait failed,process will be blocked
{
block(&sem[i].L);
return 1;
}
else
return 0;//wait succeed
}
int signal(int i)//i决定是哪个信号量
{
//s->value=s->value+1;
sem[i].value=sem[i].value+1;
printf("signal 信号量sem[%d],...sem[%d].value=%d\n",i,i,sem[i].value);
if(sem[i].value<=0)//还有阻塞的进程,将他们唤醒
{
printf("还有阻塞的进程,将他们唤醒\n");
wakeup(&sem[i].L);
return 1;
}
else
{
printf("没有阻塞的进程\n");
return 0;//没有阻塞的进程
}
}
/****************六个进程函数A,B,C,D,E,F********************/
int processA()
{
int n;
// n=k[0];//将要输入到缓冲区m的数暂存在n中
if(addr=='I') goto i1;//判断是首次进入还是中断唤醒后进入
f1: printf("生产者进程A正在运行...\n");
if(wait(0)==0)//wait succeed
{
printf("processA wait succeed\n");
goto i2;//可以将计算结果送入缓冲区
// return signal(&sem[1]);//-1还有阻塞的进程
//0没有阻塞的进程
}
else//wait failed
{
printf("processA wait failed\n");
// pcb[0].status='B';//进程A阻塞,要保存断点
return 1;
}
i1:
printf("生产者进程A被唤醒...\n");//中断唤醒后的入口地址
i2:n=k[0];//将要输入到缓冲区m的数暂存在n中
printf("生产者进程A将计算结果送入缓冲区buffer[%d]=%d\n",in,n);
//m=n;
buffer[in]=n;
in=(in+1)%Length;
signal(1); //-1还有阻塞的进程
//0没有阻塞的进程
if(--k[0]==0)
return 0;//完成标志
else
// goto f1;
{
pcb[0].status='R';//'E'-->'R',进入下一次的优先权比较
return 2;
}
}
//--------------------------------------------------
int processB()
{
int n;
// n=2*k[1];//将要输入到缓冲区m的数暂存在n中
if(addr=='I') goto i1;//判断是首次进入还是中断唤醒后进入
f1: printf("生产者进程B正在运行...\n");
if(wait(0)==0)//wait succeed
{
printf("processB wait succeed\n");
goto i2;//可以将计算结果送入缓冲区
// return signal(&sem[1]);//-1还有阻塞的进程
//0没有阻塞的进程
}
else//wait failed
{
printf("processB wait failed\n");
// pcb[0].status='B';//进程A阻塞,要保存断点
return 1;
}
i1:
printf("生产者进程B被唤醒...\n");//中断唤醒后的入口地址
i2:n=4*k[1];//将要输入到缓冲区m的数暂存在n中
printf("生产者进程B将计算结果送入缓冲区buffer[%d]=%d\n",in,n);
//m=n;
buffer[in]=n;
in=(in+1)%Length;
signal(1); //-1还有阻塞的进程
//0没有阻塞的进程
if(--k[1]==0)
return 0;//完成标志
else
// goto f1;
{
pcb[1].status='R';
return 2;
}
}
//-----------------------------------------------------
int processC()
{
int n;
// n=3*k[2];//将要输入到缓冲区m的数暂存在n中
if(addr=='I') goto i1;//判断是首次进入还是中断唤醒后进入
f1: printf("生产者进程C正在运行...\n");
if(wait(0)==0)//wait succeed
{
printf("processC wait succeed\n");
goto i2;//可以将计算结果送入缓冲区
// return signal(&sem[1]);//-1还有阻塞的进程
//0没有阻塞的进程
}
else//wait failed
{
printf("processC wait failed\n");
// pcb[0].status='B';//进程A阻塞,要保存断点
return 1;
}
i1:
printf("生产者进程C被唤醒...\n");//中断唤醒后的入口地址
i2: n=5*k[2];//将要输入到缓冲区m的数暂存在n中
printf("生产者进程C将计算结果送入缓冲区buffer[%d]=%d\n",in,n);
//m=n;
buffer[in]=n;
in=(in+1)%Length;
signal(1); //-1还有阻塞的进程
//0没有阻塞的进程
if(--k[2]==0)
return 0;//完成标志
else
// goto f1;
{
pcb[2].status='R';
return 2;
}
}
//-----------------------------------------------------
int processD()
{
if(addr=='I') goto i1;//判断是首次进入还是中断唤醒后进入
f1: //k[2]--;//首次进入
printf("消费者进程D正在运行...\n");
if(wait(1)==0)//wait succeed
{
printf("processD wait succeed:%d\n",sem[1].value);
goto i2;
// return signal(&sem[0]);//-1还有阻塞的进程
//0没有阻塞的进程
}
else//wait failed
{
printf("processD wait failed\n");
// pcb[2].status='B';//进程C阻塞,要保存断点
return 1;
}
i1:
printf("消费者进程D被唤醒...\n");//中断唤醒后的入口地址
i2:
printf("消费者进程D将打印计算结果: ");
// printf("m=%d\n",m);
printf("buffer[%d]=%d\n",out,buffer[out]);
out=(out+1)%Length;
signal(0); //-1还有阻塞的进程
//0没有阻塞的进程
if(--k[3]==0)
return 0;
else
// goto f1;
{
pcb[3].status='R';
return 2;
}
}
//------------------------------------------------------
int processE()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -