时间片轮转算法的实现

简介

优先级的算法用于多道批量处理系统可以获得满意的调度效果,但是在这种系统中,只能在优先级高的进程全部完成或发生某种事件后,才去执行下一个进程。这样,优先级较低的进程效率降低。
为此,在分时系统中通常采用时间片轮转法。

代码实现

在这里插入代#include<iostream.h>//输入输出头文件
#include<stdlib.h>//c语言函数头文件
#include<time.h>//时间和日期头文件
#include<stdio.h>//c语言标准输入输出头文件
#include<string.h>//字符串头文件

const int  MAXCOMMANDLEN =50;//进程调度宏最大值定义为50

/
//
//         PROCESS
//
/


class Process          //定义进程类               
{
friend class CPU;// 友元类函数为cpu
protected:
static int init_ID;    //随机进程ID
    int ID;      //静态常量,进程ID
char runText[MAXCOMMANDLEN]; //进程指令数组
int IP;       //进程指令指针,保存进程指令执行到具体位置
bool ISuseSource;    //逻辑变量,此进程是否使用资源,ture:使用中 false:未使用
bool ISblocked;     //此进程是否阻塞,ture:阻塞 false:未阻塞
int unitTime;     //默认进程单位被CPU执行时间1
int blockTime;     //进程被阻塞时间
public:
static void RandID();   //随机生成进程ID
Process();         //构造函数声明
int getID();    
int getIP();    
void setIP(int);
void Runed();      //进程被CPU执行
int getUnittime();     //得到进程单位执行时间
int getBlcoktime();    //得到进程阻塞时间
void setBlocktime(int);    //设置进程阻塞时间
void setUnittime(int);    //设置进程单位执行时间
char getResult(int);    //得到进程执行结果
char* getRuntext();     //得到进程执行的指令
void setBlockstate(bool);   //设置阻塞状态
bool getBlockstate();    //得到进程状态
bool getISusesource();    //得到资源的状态  使用  未使用
void setISusesource(bool);  //设置资源使用状态
};

int Process::init_ID;//重定义

void Process::RandID()//构造无参函数
{
srand( (unsigned)time( NULL ) );//随机数生成 ID
init_ID=rand();//将得到的值赋给数据带回类
}


Process::Process()//定义带参构造函数
{
ID=init_ID++;//以第一个ID为初始值,后面逐渐+1
int commandLen;//定义命令长度变量
IP=0;

cout<<"Please input the text which process runed by CPU [#command#] :>\\ ";//输出字符串
cin>>runText;//输入进程指令数组
if( (commandLen=strlen(runText) ) > MAXCOMMANDLEN )
  exit(0);//输入字符数大于宏定义正常退出

runText[commandLen]='#';    //指令结束标志#
runText[commandLen+1]='\0';//指令字符串结尾符
ISuseSource=false;//默认程序不使用资源
ISblocked=false;//默认不阻塞
unitTime=1;//默认执行时间为1
blockTime=0;//默认阻塞时间为0
}


void Process::Runed()//输出IP值+1
{
cout<<getResult(IP++);
}


int Process::getID()//存值函数得到ID
{
return ID;
}

int Process::getIP()//得到IP
{
return IP;
}

void Process::setIP(int ip)//传值函数,设置IP
{
IP=ip;
}

bool Process::getISusesource()//得到资源使用状态
{
return ISuseSource;
}

void Process::setISusesource(bool s)//设置资源使用状态
{
ISuseSource=s;
}

char* Process::getRuntext()//得到进程指令
{
return runText;
}

int Process::getUnittime()//得到执行时间
{
return unitTime;
}


int Process::getBlcoktime()//得到进程阻塞时间
{
return blockTime;
}

void Process::setBlocktime(int BT)//设置进程阻塞时间
{
blockTime=BT;
}

void Process::setUnittime(int UT)//设置进程执行时间
{
unitTime=UT;
}

void Process::setBlockstate(bool state)
{
ISblocked=state;//布尔整型变量,有两种逻辑状态变量
}

bool Process::getBlockstate()//得到进程状态,阻塞与否
{
return ISblocked;
}

char Process::getResult(int k)//返回进程数
{
  return runText[k];
}

/
//
//         SOURCE
//
/

class Source      //定义资源类 
{
protected:
int ID;         //资源的ID
bool state;        //资源状态 ture:未被占有 false:已占用
int pro_ID;        //使用资源进程ID
Process *pro;       //使用资源进程的ID
int time;        //进程使用资源的时间
public:
Source(int);
bool getState();      //得到进程状态
void setState(bool);     //设置进程状态
void setTime(int);     //设置进程使用资源时间
void setPro(Process *);   //设置使用该资源的进程
int getID();      //得到ID
int getPorID();    //得到使用资源的进程ID  
void setProID(int);    //设置使用资源的进程ID
void runned();       //资源被CPU调用
};

Source::Source(int id)//构造函数,设置id与资源使用逻辑变量
{
ID=id;
pro=NULL;
state=true;
}

void Source::setProID(int id)//设置资源进程ID
{
pro_ID=id;
}

void Source::setTime(int t)//设置资源使用时间
{
time=t;
}

void Source::setState(bool s)//设置进程状态
{
state=s;
}

bool Source::getState()//得到进程状态
{
return state;
}

void Source::setPro(Process *p)//设置使用资源的进程
{
pro=p;
}

void Source::runned()//进程运行判别
{
if(time>0) //进程未结束,输出资源ID,时间-1
{
  cout<<"( Source :"<<ID<<")";
  time--;
}
if(time<=0)      //进程使用完资源释放资源,即使用资源的时间到0   
{
  pro->setISusesource(false);//资源为已占有
  int ip=pro->getIP();//得到IP
  pro->setIP(++ip);//设置IP+1
  Source::setState(true);//资源未占有
  cout<<endl<<"The process "<<pro->getID()<<" relase the source!"<<endl;//输出进程资源被释放
  pro=NULL;//资源进程为空
}
}

/
//
//         CPU
//
/

typedef struct Block    //阻塞队列结构
{
Process *p_BlockProcess;   //被阻塞进程队列
int index;       //被阻塞的进程在就绪队列中的索引
}Block;//自定义为队列阻塞

class CPU  //定义CPU类
{
protected:
Process *p_Process;     //进程队列
Process **pp_Process;    //进程就绪队列
Block *blockQueue ;    //进程阻塞队列
Source  *p_Source;    //资源指针
int numOfprocess;     //进程数目
int numOfblock;      //阻塞进程数目
int PC;        //程序计数器
int allTime;      //CPU运行总时间
public :
CPU(int);//构造一个整型参量函数
void Run();      //CPU运行进程
bool _IC(Process&);  //虚拟IC进程指令翻译  
void useSource(Process&);  //进程申请资源
void blockProcess(Process&);       //阻塞进程
void releaseBlockPro();   //释放阻塞进程
int getAlltime();     //得到进程运行总时间
void displayPro();     //显示进程信息
void blockTimeADD();   //阻塞时间+1
};
 
CPU::CPU(int num)//构造函数以初始化数据成员的值
{
  p_Source=new Source(379857);
  numOfprocess=num;//把输入的值定义为初始化进程数
  numOfblock=0;//初始化阻塞进程数为0
  allTime=0;//初始化所需时间为0
  p_Process=new Process[numOfprocess];//开辟新空间存放进程类型数据
  pp_Process=new Process*[numOfprocess];//开辟新空间存放进程类型指针
  blockQueue=new Block[numOfprocess];//开辟新空格键存放阻塞队列结构体
  for(int i=0;i<numOfprocess;i++)//进程状态检查
  {
   pp_Process[i]=&p_Process[i];//将p_Process[i]的地址赋给指针变量pp_Process[i]
   blockQueue->p_BlockProcess=NULL;//指向被阻塞的进程队列
   blockQueue->index=-1;// 指向被阻塞的进程队列在就绪队列的索引
  }
}

int CPU::getAlltime()      //返回完成所有进程所需要的时间值
{
return allTime;
}

void CPU::displayPro()    //显示被阻塞进程基本信息
{
for(int i=0;i<numOfprocess;i++)
{
  cout<<"\tProcess ID : "<<p_Process[i].getID()<<endl;//被阻塞进程ID
  cout<<"   text of runned :"<<p_Process[i].getRuntext()<<endl;//得到被阻塞进程执行指令
}
}

void CPU::Run()//CPU运行进程
{
int numPro=numOfprocess;//初始化numPro的值为进程数numOfprocess的值

do
{
  for(int num=0;num < numOfprocess;num++)//当num值大于等于进程数时,循环结束
  {
   if(!pp_Process[num])     
//如果指针为空,该程序不在就绪队列中,结束本次循环,执行下一次循环
    continue;

   for(int t=0;t<p_Process[num].getUnittime();t++)//当程序运行时间大于执行时间,循环结束
   {
    PC=p_Process[num].getIP();//将IP的值赋给PC
    if(_IC(p_Process[num]))
    {
     if(t==0)
      cout<<"the process ["<<p_Process[num].getID()<<"] runed : ";//运行程序
     if(!p_Process[num].getISusesource())//进程未阻塞运行该程序
     {
       p_Process[num].Runed();
     }
     else
     {
       p_Source->runned();
       if( p_Source->getState() && numOfblock>0 )    //释放阻塞进程,运行下一个就绪程//序
       {
        releaseBlockPro();
       }
     }
    }
    else
    {
     if(!p_Process[num].getBlockstate())//程序不在阻塞队列中
     {
      numPro--;//程序序号-1
         pp_Process[num]=NULL;//直至程序序号为0
      continue;
     }
     break;//跳出
    }
    allTime++;//程序运行总时间+1
    if(numOfblock>0)//被阻塞进程数>0
     blockTimeADD();//阻塞时间+1
   }//end for t...//更新进程时间
   if( p_Process[num].getUnittime() )//得到进程执行时间
    p_Process[num].setUnittime(1);
   cout<<endl;
  }//end for num...//更新进程

}while(numPro); 
}

bool CPU::_IC(Process &p) //对进程中的指令进行翻译
{

char resultRunned;

resultRunned=p.getResult(PC);//得到的进程指令赋给resultRunned
if(resultRunned=='#')//指令为#直接结束
  return false;
else
{
  if(resultRunned=='$')      //申请资源指令
  {
   PC++;//程序计数+1
   p.setIP(PC);//设置PC的IP
   resultRunned=p.getResult(PC);//将PC运行结果赋给resultRunned
   if( resultRunned >='1' && resultRunned <='9' )
   {
    if(p_Source->getState())//得到进程资源状态
    {
     useSource(p);
     cout<<"The process "<<p.getID()<<" take up the source!"<<endl;//资源未被使用则使用资源
    }
    else
    {
     blockProcess(p);
     cout<<"The process "<<p.getID()<<" is blocked !"<<endl;//资源被使用阻塞进程
     return false;

    }
   }
   else
   {
    cout<<"The process ["<<p.getID()<<"] runned fail ! It has been stopped! "
		<<endl;//提示$后不是数字,应为字符串,语法错误
    return false;
   }
  }

}
  return true;
}

void CPU::blockTimeADD()
{
for(int i=0;i<numOfblock;i++)
{
  int BT=blockQueue[i].p_BlockProcess->getBlcoktime();//将进程阻塞时间赋给BT
  blockQueue[i].p_BlockProcess->setBlocktime(++BT);//设置所有阻塞程序阻塞时间
}
}

void CPU::useSource(Process& p)
{
p.setISusesource(true);//设置进程资源状态为未被占有
p_Source->setState(false);//资源被占用
p_Source->setProID(p.getID());//设置资源进程ID
p_Source->setTime(p.getResult(PC)-'0');//设置资源进程计数
p_Source->setPro(&p);//设置使用该资源进程
}

void CPU::blockProcess(Process& p)
{
int tempIndex=numOfprocess-( Process::init_ID-p.getID() );//程序数为程序ID赋给tempIndex
blockQueue[numOfblock].p_BlockProcess=&p;// 阻塞程序放入就绪队列
blockQueue[numOfblock].index=tempIndex;//tempIndex赋给进程阻塞队列
numOfblock++;//阻塞进程数+1
int ip=p.getIP();//程序IP赋给ip
p.setIP(--ip);//ip-1
p.setBlockstate(true);//设置阻塞进程
p.setBlocktime(1);//阻塞时间为1
p.setUnittime(0);//进程执行时间为0
pp_Process[tempIndex]=NULL;//就绪队列为空

}

void CPU::releaseBlockPro()//释放阻塞进程
{
//释放阻塞队列第一个进程,第一个时间最长
pp_Process[blockQueue[0].index]=blockQueue[0].p_BlockProcess;//进程阻塞队列放入index
blockQueue[0].index=-1;//阻塞队列
blockQueue[0].p_BlockProcess->setBlockstate(false);//设置阻塞程序阻塞状态为阻塞·
blockQueue[0].p_BlockProcess->setUnittime( blockQueue[0].p_BlockProcess->getBlcoktime() );
//得到程序阻塞时间
blockQueue[0].p_BlockProcess->setBlockstate(0);//得到阻塞程序状态为未阻塞
blockQueue[0].p_BlockProcess=NULL;//阻塞就绪队列进程数为0
numOfblock--;//阻塞进程数-1


for(int i=0;i<numOfblock;i++)//阻塞队列向前移动一个位置
{
  blockQueue[i]=blockQueue[i+1];
}
}


/
//
//        The main progress
//
/


void main()
{
int num;//进程数量
cout<<"\t********************************************************"<<endl
  <<endl;
cout<<"\t             The virtual CPU    the process runned           "
<<endl
  <<endl;
cout<<"\t*******************************************************"<<endl
  <<endl;

cout<<"initialize the information of processes "<<endl;

cout<<"Please input the number of process [#command#] >\\ ";
//检查输入数据是否正确
try
{
cin>>num;//输入进程数
if(num<=0)
  throw(num);//抛出异常数据
}
catch(int)//接受抛出数据
{
  cout<<"You input the numbers of process is error !"<<endl;
  exit(1);//异常将1返回系统
}

Process::RandID();   //随机生成第一个进程ID,以后进程ID+1
CPU virtualCPU(num);//定义CPU类对象,同时将num传入CPU构造函数中

cout<<"Pocesses runed by CPU "<<endl;
virtualCPU.Run();//通过对象访问CPU中Run函数

cout<<"Processes runned over ! "<<endl;
cout<<"\t********************************************************"<<endl
  <<endl;
cout<<"\t The time which processes runned by CPU : "
<<virtualCPU.getAlltime()<<endl
  <<endl;
virtualCPU.displayPro();
cout<<"\t*******************************************************"<<endl
  <<endl;
}
//这里没有API调用 只是模拟,将进程设定为自己的语法,输入一般的字符,CPU
调用时只是正常输出,如果遇到'$'表示该进程要调用系统资源后面必须跟一个数字表示占有的时间,如果资源闲置则占有资源否则资源阻塞,等资源释放再占有资源。进程的调用算法采用的是时间片轮转算法并有所改进,当某个进程从阻塞队列释放后,它将把以前因为等待资源而被浪费的时间补回来。
码片

运行结果展示
1、不调用资源
在这里插入图片描述

执行4个程序,编号为1,2,3,4,不调用资源,程序直接结束,默认程序运行时间为1秒,程序运行总时间为4秒。

2、调用系统资源

在这里插入图片描述
在这里插入图片描述

执行4个程序,编号为1,2,3,4,默认程序执行时间为1秒,程序1调用系统资源时间为1秒,2调用系统资源时间为2秒,3调用系统资源时间为3秒,4调用系统资源时间为4秒,
程序运行总时间为1+2+3+4+1*4=14秒。
3、程序阻塞

在这里插入图片描述
在这里插入图片描述

执行3个程序,编号为1,2,3,程序执行时间为1秒,由于程序1调用系统资源为2秒,故程序2阻塞1秒,程序1运行结束释放资源后,程序2才能调用资源,估程序运行总时间为12秒。
4、程序异常

(1)、输入程序编号大于50位,超出定义值,程序出错
在这里插入图片描述

(2)、系统调用符后未跟时间或输入不正确

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值