⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wros2new.cpp

📁 操作系统相关的东东 操作系统相关的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -