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

📄 sun.cpp

📁 本次程序的题目为:进程管理——支持多个进程并发运行的简单的进程管理模拟系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <iostream.h>
#include <string.h>

#define  TRUE      1
#define  FALSE     0
#define  MAXPRI    100
#define  MAX       9
#define  NIL       -1
#define  USE       0
#define  UNUSE     -1

struct   {
	  int      id;//进程身份(即:内部标识符,如:0,1,2)
	  char     status;//进程状态,可为E、R、T、W和C;
	                  //系统为进程设置了5种运行状态:
	                               //E -- 执行态;
	                               //R -- 高就绪态;
	                               //T -- 低就绪态(执行进程因时间片到限而转入);
	                               //W -- 等待态;
	                               //C -- 完成态。
	                               //各进程的初始状态均设置为R。
	  int      nextwr;   //等待链指针,指示在同一信号量上等待的下一个进程的标识数。
	  int      priority;//进程优先数;
	  int      flags;   //用于标志此PCB是否可用:
	                    //(USE表示PCB已创建 or UNUSE表示PCB未创建)
	  int      identify;//外部标识符
	  }
	  pcb[MAX];  //PCB[i]的信息
struct   {
	  int      value; //信号量值,初值为1
	  int      firstwr;//等待链首指针,指示该信号量上等待的第一个进程的标识数
	  }
	  sem[2];  //信号量的信息
struct   {
	  int      comer;   //信息发送者(send message)
	  int      info_num;//发来得信息数(messages's number)
	  int      mutex;   //信箱同步信号量(USE表示信箱可使用 or UNUSE表示信箱不可使用)
	  int      boxflag;//信箱存在否的标志
	  }
      box[MAX];  //进程i的信箱
char     savearea[MAX][4],addr;//现场保留区,用数组SAVEAREA[MAX][4]表示。
              //即每个进程都有一个大小为4个单元的保留区,用来保存被"中断"时的现场信息,
              //如通用寄存器的内容和断点地址等。
int      s1,s2;
              //两个公共变量,用作共享临界资源。
int      i;   //用来模拟一个通用寄存器;
int      seed;
int      exe=NIL;//执行进程指针,其值为进程标识数;
int      count[MAX+1];//可用PCB索引:
                      //其中:count[0..MAX-1]分别标识pcb[0..MAX-1](1为存在,0反之)
                      //count[MAX]为还可创建的PCB个数
int      remark=1; //用于记录外部标识符的标识数
int      wentdown[3*MAX];//用于记录已撤消的进程号
int      cx;//已撤消的进程数组计数器

//***函数声明***
void init();       //初始化创建原语
int  find();       //从就绪队列中选择一进程变为执行态
int p  (int se,char ad);  //p操作
int v  (int se, char ad); //v操作
void create();        //创建原语
void deleted(int n);  //撤消原语 
void block  (int se); //阻塞原语
void wakeup (int se); //唤醒原语
void eexit  (int n);  //进入终止态
void process();  //各进程须完成的操作流程
int scheduler(); //操作系统的进程调控
void analyse();  //判断是否添加新进程
bool timeint(char ad); //时间片中断函数
void time_silk();      //时间片单元函数(细分时间片到每一步)
void call_time();      //调用时间函数
void inform();  //发送消息函数(进程通信)
void recive();  //接收消息函数
//***

void init()          //   Initialization   
{
   //%%%%%为进程创建PCB %%%%%
  for(int j=0;  j<3;  j++)
     {
      pcb[j].id      =j; //给进程身份(如:1,2,3...)赋值
      pcb[j].status  ='r';//进程状态(可为E、R、T、W和C) 
	                      //R -- 高就绪态;
      pcb[j].nextwr  =NIL;//等待链指针,指示在同一信号量上等待的下一个进程的标识数。
      printf("\n Process %d priority?",j+1);//***输入各进程优先级***
      scanf("%d",&i);
      pcb[j].priority=i;  //***
	  pcb[j].identify=j+1;//外部标识符
	  pcb[j].flags=USE;   //标识PCB已创建
	  count[j]=1; //***修改'可用PCB索引'***
	  count[3]--; //*****
	  remark++; //修改'外部标识符的标识数'的记录
	  box[j].mutex=USE;//信箱可使用
	  box[j].boxflag=USE;
      }
    //%%%%%————————%%%%%

    //#####为各信号量赋初值#####
  sem[0].value=1;  
  sem[0].firstwr=NIL;
  sem[1].value=1;   
  sem[1].firstwr=NIL;
    //#####————————#####

  for(i=0;  i<MAX;  i++)   //***现场保留区,\
	                     //用数组SAVEAREA[MAX][4]表示***
     for(j=0;  j<4;  j++)
	savearea[i][j]='0';  //***

  for(j=0;j<3*MAX;j++)   //***已撤消的进程数组为空***
	  wentdown[j]=-1;  //***
  cx=0;

  //&&&&&&&&-------------&&&&&&&&&&&
  for(j=3;j<MAX;j++)        //********给不存在的PCB,BOX及未用对应PCB索引赋值*********
  {
   pcb[j].status  ='c';
   pcb[j].flags=UNUSE;
   box[j].mutex=USE;
   box[j].boxflag=UNUSE;
   pcb[j].identify=-1;
  }
  for(j=3;j<MAX;j++)
  {
  count[j]=0;
  }                       //**************************
  //&&&&&&&&--------------&&&&&&&&&&
  count[MAX]=MAX-3;      //还创建的PCB个数
}

 double  random() //产生随机数的程序,表明各进程行动的异步性
{
  int   m;

  if(seed<0)    m=-seed;
	else    m=seed;

  seed=(25173 * seed +13849) % 65536;

  return  (m / 32767.0);
}


bool timeint  (char ad)     /*  Time  slice  interrupt  */
{
  double    x;

  x=random();

  for(double yi=0.00;yi<1.00;yi+=(1.00/MAX))
	if((x<yi)&&(exe==(yi*MAX)))  return (FALSE);

    //***现场保留区***
  savearea[exe][0]=i; //记录程序执行到的地方(即:该程序执行到了第几圈)	                    
  savearea[exe][1]=ad;//记录时间片用完时程序所处的状态

  pcb[exe].status='t';//PCB中记录程序因Time  slice用完而中断
    //******

  printf("\tTime slice interrupt .\n\tprocess %d enter into ready.\n",pcb[exe].identify);

  exe=NIL;   //记录当前正在运行的进程为无

  return  (TRUE);
}


int scheduler   ()
{
  int    pd;

  if(count[MAX]!=0)  //分析是否创建进程
	  analyse();
  
  if((pd = find()) == NIL  &&  exe == NIL) //判断是否退出系统
     return  (NIL);     /*   Quit system */

  if(pd != NIL)
  {
     if(exe == NIL)//***若当前执行程序为无*** 
	 {
      pcb[pd].status='e';//将状态变为执行态
      exe=pd;
	  call_time(); //调用时间
   	  printf("Process %d is executing.\n",pcb[exe].identify);
	  recive();    //收消息
	  inform();    //发消息

	 }             //******
     else //***若当前执行程序非空*** 
       if(pcb[pd].priority < pcb[exe].priority)//@@@判断优先级高低@@@
		                                  //若优先级高于当前执行程序
	   {
	    pcb[exe].status='r';
	    printf("\tProcess %d enter into ready.\n",pcb[exe].identify);
	    pcb[pd].status='e';  //将状态变为执行态
	    exe=pd;
		call_time();  //调用时间
	    printf("Process %d is executing.\n",pcb[exe].identify);
		recive();  //收消息
		inform();  //发消息
	   }  //@@@@@@
  }

     i   =savearea[exe][0]; //恢复程序执行到的地方(圈数)
     addr=savearea[exe][1];
     
     return  (exe);
}

int find()  //~~~~~寻找应该吊为执行程序的进程~~~~~
{
 int j;  //用于循环计数
 int pd=NIL;//记录应吊为执行态的进程
 int w=MAXPRI;//设置一个哨兵来寻找最高优先的进程

 for(j=0; j<MAX; j++) //*****判断是否存在高就绪*****
	 if(pcb[j].status == 'r')
     if(pcb[j].priority < w)
	 { 
	    w =pcb[j].priority;
	    pd=j;
	 }            //**********

 if(pd == NIL)  //*****若不存在高就绪,则判断是否存在低就绪*****
   for(j=0; j<MAX; j++)
     if(pcb[j].status == 't')
       if(pcb[j].priority < w)
       {
	    w =pcb[j].priority;
	    pd=j;
	   }         //**********

 return  (pd);//返回应吊为执行态的进程

}

int p  (int se,char ad)
{
 if(--sem[se].value >= 0) //判断(信号量)临界区是否可进入
   return  (FALSE);//可,则执行

 block(se);        //不可,则阻塞
 savearea[exe][0]=i;  //记录程序执行到的地方	                    
 savearea[exe][1]=ad;//记录时间片用完时程序所处的状态
 exe=NIL;  //

 return  (TRUE);
}

void block  (int se)
{
 int  w;

 printf("\tProcess %d is block.\n",pcb[exe].identify);

 pcb[exe].status='w'; //将程序PCB置为等待态
 pcb[exe].nextwr=NIL; //等待链指针,\
                      //指示在同一信号量上等待的下一个进程的标识数
//***等待链首指针,指示该信号量上等待的第一个进程的标识数***
 if((w = sem[se].firstwr) == NIL)
     sem[se].firstwr=exe;
 //***firstwr***

//等待链指针,指示在同一信号量上等待的下一个进程的标识数
 else
     {
      while(pcb[w].nextwr != NIL)
	     w=pcb[w].nextwr;
      pcb[w].nextwr=exe;
      }
 //***nextwr***

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -