本文主要用来分享基于时间片轮转的进程调度算法,但是在分享之前,我还是先来整理一下关于进程调度的基本理论。
调度是决定或者安排事物发展次序的策略。进程的调度就是决定哪个进程来使用处理机。
操作系统的3级调度:
1.作业调度,又叫高级调度。决定将外存上的哪些作业调到内存的就绪队列,等待执行。
2.进程调度,又叫低级调度,决定就绪队列中的哪个进程将获得处理机。
3.交换调度,又叫中级调度,为了提高内存的利用率和系统的吞吐量(单位时间内完成工作量
总和
),也就是将内存中的作业调到外存去
等待。
调度的类型:
1.仅有进程调度的调度队列模型,运用在分时系统中。
2.具有高级和低级调度的调度队列模型。
3.具有3级调度的调度队列模型(批处理系统中)。
进程调度的方式:
1.非剥夺式:一旦占有处理机,直至完成或者阻塞。
2.剥夺式:就是可以剥夺别的进程占有的处理机。
剥夺有以下原则:
a.短作业优先
b.时间片轮转
c.优先权原则
什么样的情况才会引起进程调度??
·正在执行的进程执行完毕。
·执行中的进程遇到输入输出。
·时间片完成
·在进程通信或者同步的过程中执行了某些操作,如p操作(让权等待)。
·高优先者进入(在实时系统)
时间片轮转的进程调度算法,就是每个进程执行给定的时间片,时间片执行完之后,就将处理机让给其他的进程去使用。下边给出
基于时间片轮转的进程调度算法的实现代码:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<queue>
int roundTime = 1;//定义时间片为1
//进程信息节点
typedef struct NodeInfo
{
char m_name;//进程名称
int m_arriveTime;//进程的到达时间
int m_totalTime;//进程执行完成需要的总时间
int m_doneTime;//进程已经执行的时间
int m_restTime;//进程还需要的执行的时间
friend istream& operator>>(istream& is,NodeInfo& x)//进程信息的输入
{
is>>x.m_name>>x.m_arriveTime>>x.m_totalTime>>x.m_doneTime>>x.m_restTime;
return is;
}
friend ostream& operator<<(ostream& os,NodeInfo& x)//进程信息的输出
{
cout<<x.m_name<<" " <<x.m_arriveTime<<" "<<x.m_totalTime<<" "<<
x.m_doneTime<<" "<<x.m_restTime<<endl;
return os;
}
} NodeInfo;
class Scheduling
{
public:
Scheduling()
{}
//新的进程进入就绪队列
void PushNewProcess(const NodeInfo& x)
{
_ready.push(x);
}
//按照时间片轮转进行执行
void ServerProcess()
{
if(_ready.empty())
return;
NodeInfo top = _ready.front();//找到队首进程
while(!_ready.empty())
{
top = _ready.front();//找到队首进程
top.m_restTime -= roundTime;
top.m_doneTime += roundTime;
if(top.m_restTime != 0)
{
_ready.pop();
_ready.push(top);
}
else
{
_ready.pop();
_finish.push(top);
}
Print();
}
}
//打印出进程的相关信息
void Print()
{
queue<NodeInfo> tmp;
NodeInfo top;
cout<<"name"<<" "<<"arriveTime"<<" "<<"totalTime"<<" "<<"doneTime"<<" "<<"restTime"<<endl;
while(!_ready.empty())
{
top = _ready.front();
cout<<top;
tmp.push(top);
_ready.pop();
}
//就绪队列中的进程信息,已经打印完成,将tmp里的信息转至就绪队列
while(!tmp.empty())
{
top = tmp.front();
_ready.push(top);
tmp.pop();
}
while(!_finish.empty())
{
top = _finish.front();
cout<<top;
tmp.push(top);
_finish.pop();
}
//完成队列中的进程信息,已经打印完成,将tmp里的信息转至完成队列
while(!tmp.empty())
{
top = tmp.front();
_finish.push(top);
tmp.pop();
}
}
private:
queue<NodeInfo> _ready;//就绪队列
queue<NodeInfo> _finish;//完成进程的队列
};
void menu()
{
cout<<"------基于时间片轮转的进程调度算法------"<<endl;
cout<<"------0.退出系统------"<<endl;
cout<<"------1.输入新的作业进入就绪队列--------"<<endl;
cout<<"------2.服务作业------"<<endl;
cout<<"请选择>:";
}
void Test()
{
menu();
//用作测试
/*NodeInfo p[] = {{'A',0,4,0,4},
{'B',1,2,1,1},
{'C',2,5,0,5}};
*/
int choose = 0;
Scheduling s;
NodeInfo newPro;
do
{
cin>>choose;
switch(choose)
{
case 1:
{
cout<<"请输入进程的名称,到达时间,总共服务时间,已服务时间,还需服务时间"<<endl;
cin>>newPro;
s.PushNewProcess(newPro);
break;
}
case 2:
{
s.ServerProcess();
break;
}
case 0:
return;
default:
break;
}
cout<<"请选择>:";
}while(choose > 0);
}
程序运行结果如下: