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

📄 d.cpp

📁 CPU进程调度算法,采用多极队列调度算法,可是有一个问题,会不断运行
💻 CPP
字号:
#include   <string.h>
#include   <time.h>
#include   <iostream.h>
#include   <iomanip.h>
#define    sheet 5      //定义了时间片为10秒

//定义一个pcb的结构体 
struct pcb{
 int   id;             //作业编号
 char  Index;          //执行指令
 char  status;         //当前状态
 int   time;           //执行时间  
 int   Num;            //作用是识别出就绪队列中的进程,然后在进程数组中找到它,以便修改或参考
 int   flat;           //用来指示在阻塞队列中它是否已经被唤醒
};
 
pcb jobpcb[100];        //设置进程数组用来表示每个进程的状态,供调度进程时参考或修改
char jobp[3][50];       //作业
struct Qnode//队列
{
 pcb pcb[100];       //pcb编号          
 int head,tail; 
};
 
//延迟Time时间
void delay(int Time){
 long begin,end;
 time(&begin);
 cout<<"等待中..........."<<endl;
 do{
  time(&end);
 }while((end-begin)<Time);
 cout<<"完成"<<'\n'<<'\n';
}
 
//字符转化为数值                 
int  change(char * m){  
 int i,j=0;
    int len=strlen(m);
    for(i=0;i<len;i++)
      j=j*10+m[i]-'0';
 return j;
}
 
//显示每个作业进程的分配情况
void displayIndex(int i,int num,Qnode * l){
 int j;
 cout<<"Job "<<i+1<<" : "<<endl;
 cout<<'\t'<<"pcbnum"<<'\t'<<"Index:"<<'\t'<<"time:"<<endl;
 for(j=l->tail-num;j<l->tail;j++)
  cout<<setw(10)<<j+1<<setw(8)<<l->pcb[j].Index<<setw(8)<<l->pcb[j].time<<endl;
}
 

void  creatpcbline(Qnode * l)//创建进程程序
{  
     int i,ll,ln,bpos,pos,num;
  char buff[50];
  cout<<"下面是各个作业的进程分配情况:"<<'\n';
  for(i=0;i<3;i++){
         ln=strlen(jobp[i]);
   pos=0;     ll=0;    num=0;
   while(pos<ln){
    while(jobp[i][pos]==' ')    
		      pos++;                   //去空格
      if(pos==ln)  break;                                  //很重要
    l->pcb[l->tail].Index=jobp[i][pos];                  //给作业中每条指令赋名字
    l->pcb[l->tail].Num=l->tail; 
    jobpcb[l->tail].Index=jobp[i][pos++];
    l->pcb[l->tail].status='r';
       jobpcb[l->tail].status='r';
       l->pcb[l->tail].id=i;
       jobpcb[l->tail].id=i;
    while(jobp[i][pos]==' ')    pos++;
    bpos=0;
    while(jobp[i][pos]!=' '&&jobp[i][pos]!='\0')         //判断扫描是否到尽头了很重要
     buff[bpos++]=jobp[i][pos++];
            //buff里存放的是每个进程需要的时间,是字符类型的,所以下面要用chang函数来把他转换成整型
    buff[bpos]='\0';
    l->pcb[l->tail].time=change(buff); 
    jobpcb[l->tail].time=change(buff);
    (l->tail)++;
    num++;
   }
   displayIndex(i,num,l);
  }
  l->tail -= 1 ;
}

/*初始化队列*/
void  initqueue(Qnode * l)
{ 
 l->head=0;
 l->tail=0;
 for(int i=0;i<100;i++)
  l->pcb[i].flat=0;                   //flat=0表示在就绪队列中没有被唤醒
}
 
//插入队列
void insertqueue(Qnode * l,pcb PCB)
{
 (l->tail)++;
 l->pcb[l->tail].id=PCB.id;
 l->pcb[l->tail].Index=PCB.Index;
 l->pcb[l->tail].Num=PCB.Num;
 l->pcb[l->tail].status=PCB.status;
 l->pcb[l->tail].time=PCB.time;
}

//判断进程是否可以运行
int IsAllReady(int i)
{
 for(int j=0;j<i;j++)
  if(jobpcb[j].id==jobpcb[i].id)
   if(jobpcb[j].status!='F')  return 0;               //'F'表示已完成
 return 1;
}

//唤醒被阻塞的进程
void WakeUp(Qnode * l,Qnode Queue0,Qnode Queue1,Qnode Queue2,Qnode Queue3)
{
 for(int i=0;i<=Queue0.tail;i++){
  if(  (l->pcb[l->head].Num==Queue0.pcb[i].Num-1)  &&   Queue0.pcb[i].flat==0 ){
   insertqueue(l,Queue0.pcb[i]);
   Queue0.pcb[i].flat=1;                                //表示该进程已被唤醒
   break;
  }
 }
 for(i=0;i<=Queue1.tail;i++){
  if(  (l->pcb[l->head].Num==Queue1.pcb[i].Num-1)  &&   Queue1.pcb[i].flat==0 ){
   insertqueue(l,Queue1.pcb[i]);
   Queue1.pcb[i].flat=1;                                //表示该进程已被唤醒
   break;
  }
 }
 for(i=0;i<=Queue2.tail;i++){
  if(  (l->pcb[l->head].Num==Queue2.pcb[i].Num-1)  &&   Queue2.pcb[i].flat==0 ){
   insertqueue(l,Queue2.pcb[i]);
   Queue2.pcb[i].flat=1;                                //表示该进程已被唤醒
   break;
  }
 }
 for(i=0;i<=Queue3.tail;i++){
  if(  (l->pcb[l->head].Num==Queue3.pcb[i].Num-1)  &&   Queue3.pcb[i].flat==0 ){
   insertqueue(l,Queue3.pcb[i]);
   Queue3.pcb[i].flat=1;                                //表示该进程已被唤醒
   break;
  }
 }
}

//处理每个进程
int DealwithProcess(char cmd,Qnode * l,Qnode Queue[])
{
 if(l->pcb[l->head].time<=sheet){
  if(cmd=='h')    { (l->head)++;    return 0;  }
  else{
   cout<<"第"<<l->pcb[l->head].id+1<<"个作业里的第"<<(l->pcb[l->head].Num+1)%4<<
    "个进程执行"<<l->pcb[l->head].time<<"秒"<<endl;
   delay(l->pcb[l->head].time);
   jobpcb[   l->pcb[l->head].Num   ].status='F'; 
   WakeUp(l,Queue[0],Queue[1],Queue[2],Queue[3]);
   (l->head)++;
   return 1;
  }
 }
 else{
  cout<<"第"<<l->pcb[l->head].id+1<<"个作业里的第"<<(l->pcb[l->head].Num+1)%4<<
   "个进程执行"<<sheet<<"秒"<<endl;
  delay(sheet);
  l->pcb[l->head].time -= sheet;
  insertqueue(l,l->pcb[l->head]);
  (l->head)++;
  return 1;
 }
}

//开始执行作业
int run(Qnode * l,Qnode Queue[])
{
while(1)
{
  if(    IsAllReady( l->pcb[l->head].Num )     )
  {
     if(  DealwithProcess(l->pcb[l->head].Index,l,Queue)  )   continue;
      else
	  {   
        if(l->pcb[l->head-1].Index=='h'&&l->pcb[l->head-1].id==2)
		{ 
             cout<<"     第"<<l->pcb[l->head-1].id+1<<"个作业已完成!"<<'\n'<<endl;
             return 1;
		}
     cout<<"     第"<<l->pcb[l->head-1].id+1<<"个作业已完成"<<'\n'<<endl;
	  }
  }
 else
  {
   char cmd;
   

   cmd=l->pcb[l->head].Index;
   switch(cmd){
   case 'c': insertqueue(&Queue[0],l->pcb[l->head]); (l->head)++; break;
   case 'i': insertqueue(&Queue[1],l->pcb[l->head]); (l->head)++; break;
   case 'o': insertqueue(&Queue[2],l->pcb[l->head]); (l->head)++; break;
   case 'h': insertqueue(&Queue[3],l->pcb[l->head]); (l->head)++; break;
   }
  }
 }
}

//初始化
void InitFile(Qnode Queue[])
{
 int i;
 strcpy (jobp[0]," c 20 i 20 o 15 h 0 ");              
 strcpy (jobp[1]," i 10 c 20 c 10 h 0 ");
 strcpy (jobp[2]," c 30 i 20 c 5  h 0 ");
 for(i=0;i<4;i++)
  initqueue(&Queue[i]);
 Queue[4].head=Queue[4].tail=0;
 for(i=0;i<100;i++)//每个进程的初始值
 {
  jobpcb[i].id=-1;
  jobpcb[i].status='r';
  jobpcb[i].Index=' ';
  jobpcb[i].time=0;
  jobpcb[i].Num=-1;
  jobpcb[i].flat=-1;
 }
}

void main()
{
 cout<<"           ---------------------------------------------------"<<endl;
 cout<<"           ||                                               ||"<<endl;
 cout<<"           ||              进程调度模拟实验                 ||"<<endl; 
 cout<<"           ||                                               ||"<<endl; 
 cout<<"           ||                                               ||"<<endl; 
 cout<<"           ||                                               ||"<<endl; 
 cout<<"           ---------------------------------------------------"<<endl;
 Qnode  Queue[5];            //5个队列    0C  1I  2O  3H  4R   //1,2,3分别为C,I,O阻塞队列,4为就绪队列
 InitFile(Queue);
 creatpcbline(&Queue[4]);
 cout<<"输入s,按回车键开始作业"<<'\n';
 char a;
 cin>>a;
while(a!='s'){//判断输入是否为S
  cout<<"输入s,按回车键开始作业"<<'\n';
  cin>>a;
 }
 run(&Queue[4],Queue);
} 



⌨️ 快捷键说明

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