简介
优先级的算法用于多道批量处理系统可以获得满意的调度效果,但是在这种系统中,只能在优先级高的进程全部完成或发生某种事件后,才去执行下一个进程。这样,优先级较低的进程效率降低。
为此,在分时系统中通常采用时间片轮转法。
代码实现
在这里插入代#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)、系统调用符后未跟时间或输入不正确