操作系统中进程调度是处理及管理的核心内容。
阅读本文,需要有一定的C/C++、数据结构基础。
内容介绍
采用C++编写程序,选用优先数调度算法或简单轮转法对五个进程进行调度,每个进程处于运行(Run)、就绪(Ready)和完成(Finish)三种状态之一,并假定起始状态为就绪状态。
-
进程控制块结构
-
进程控制块的链结构
其中:
Run——表是当前运行进程指针,
Ready——就绪队列头指针
Tail——就绪队列尾指针
Finish——完成队列指针 -
算法说明
(1) 为了便于处理,程序中进程的运行时间以时间片为单位进行计算,各进程的优先数或轮转时间片数,以及进程需要运行的时间片数,其初始值均有用户给定。
(2) 优先数法
进程就绪队列按优先数大小从高到低排列,链首进程首先投入运行。进程每执行一次,进程需要的时间片数减1、该进程的优先数减3。这样,该进程如果在一个时间片中没有完成,其优先数降低一级。接着仍是用该进程降低一级后的优先数与就绪队列中链首进程的优先数进行比较,如果仍是该进程的优先数高或相同,便让该进程继续执行;否则,调度就绪队列的链首进程投入运行。原运行过的进程按其现行优先数大小插入就绪队列,且改变它们对应的进程状态,一直到所有进程都运行完各自的时间片数。
(3) 简单轮转法
进程就绪队列按各进程进入的先后顺序排列。进程每次所需处理机的轮转式按其重要程度记入进程控制块中的轮转时间片数记录项。进程执行时,每运行一个时间片,进程还需要的时间片数减1,运行进程占用处理机的时间片数加1,然后比较占用CPU的时间片数是否与该进程的轮转时间片数相等,若相等则说明已达到轮转时间,应将现运行的进程排列就绪队列的末尾,调度队列上的首进程运行,且改变它们的进程状态,直至所有进程完成各自的时间片。 -
程序框图
(1)优先数调度
(2)时间片轮转调度
代码实现
#include <iostream>
#include <queue>
/**
/*实现优先级调度算法和轮转时间片调度算法
/*author:灯光也暗了丶
**/
using namespace std;
struct process{
int pid;//进程编号,由输入时顺序决定、
string statu;//进程目前状态
int rotation;//已占用CPU时间
int priority;//优先级
int occupy_num;//轮转时间上限
int need_cpu;//进程目前还需CPU时间片数
process* next;
bool operator<(process p)const{
return priority < p.priority;
}
};
priority_queue<process>readyqueue_priority;//优先级调度算法就绪队列
queue<process>readyqueue_roation;//轮转调度算法队列
/*优先级调度算法就绪队列输出*/
void outPriority(priority_queue<process>q,process cur){
cout<<"----------------"<<"process: "<<cur.pid<<"------------------"<<endl;
cout<<"statue: "<<cur.statu<<endl;
cout<<"Needing CPU: "<<cur.need_cpu<<endl;
cout<<"Priority: "<<cur.priority<<endl;
while(!q.empty()){
cur = q.top();
q.pop();
cout<<"----------------"<<"process: "<<cur.pid<<"------------------"<<endl;
cout<<"statue: "<<cur.statu<<endl;
cout<<"Needing CPU: "<<cur.need_cpu<<endl;
cout<<"Priority: "<<cur.priority<<endl;
}
cout<<"\none clock pass"<<endl;
}
/*轮转调度算法就绪队列输出*/
void outRotation(queue<process>q,process cur){
cout<<"----------------"<<"process: "<<cur.pid<<"------------------"<<endl;
cout<<"statue: "<<cur.statu<<endl;
cout<<"Needing CPU: "<<cur.need_cpu<<endl;
cout<<"The limit of occupying CPU: "<<cur.occupy_num<<endl;
cout<<"Had occupied CPU: "<<cur.rotation<<endl;
while(!q.empty()){
cur = q.front();
q.pop();
cout<<"----------------"<<"process: "<<cur.pid<<"------------------"<<endl;
cout<<"statue: "<<cur.statu<<endl;
cout<<"Needing CPU: "<<cur.need_cpu<<endl;
cout<<"The limit of occupying CPU: "<<cur.occupy_num<<endl;
cout<<"Had occupied CPU: "<<cur.rotation<<endl;
}
cout<<"\none clock pass"<<endl;
}
/*优先级调度算法实现*/
void priority_ctrl(){
while(!readyqueue_priority.empty()){
process cur_p = readyqueue_priority.top();//链首进程
readyqueue_priority.pop();
cur_p.statu = "Run";
process top_pro = readyqueue_priority.top();
while(cur_p.priority>=top_pro.priority)
{
outPriority(readyqueue_priority,cur_p);//判断优先数是否大于链首进程
cur_p.priority-=3;
cur_p.need_cpu--;
if(cur_p.need_cpu==0){
cur_p.statu = "Finish";
cout<<"\n\nFinish: "<<cur_p.pid<<endl;
break;
}
}
if(cur_p.statu!="Finish"){
cur_p.statu = "Ready";
readyqueue_priority.push(cur_p);
}
}
cout<<endl;
}
/*轮转调度算法实现*/
void rotation_ctrl(){
while(!readyqueue_roation.empty()){
process cur_p = readyqueue_roation.front();
readyqueue_roation.pop();
cur_p.statu = "Run";/*置当前进程状态为运行*/
while(cur_p.rotation<cur_p.occupy_num)//判断占用CPU时间是否达到轮转
{
outRotation(readyqueue_roation,cur_p);
cur_p.rotation++;
cur_p.need_cpu--;
if(cur_p.need_cpu==0){
cur_p.statu = "Finish";
cout<<"\n\nFinish: "<<cur_p.pid<<endl;
break;
}
}
if(cur_p.statu!="Finish"){
cur_p.statu = "Ready";
cur_p.rotation = 0;
readyqueue_roation.push(cur_p);
}
}
cout<<endl;
}
int main()
{
int n;
cout<<"Input total process: "<<endl;
cin>>n;
cout<<"Choose process control way:"<<endl<<"1:Priority"<<endl<<"2:Rotation"<<endl;
int choose;
cin>>choose;
process p;
if(choose==1){
cout<<"Input "<<n<<" pairs of "<<"need_CPU and priority: (separate with SPACE)"<<endl;
p.statu = "Ready";
p.occupy_num = 1;
p.rotation = 1;
p.next = NULL;
for(int i=1;i<=n;i++){
p.pid = i;
cin>>p.need_cpu>>p.priority;
readyqueue_priority.push(p);
}
priority_ctrl();
}
else{
cout<<"Input "<<n<<" pairs of "<<"need_CPU and occupy_TIME: (separate with SPACE)"<<endl;
p.statu = "Ready";
p.priority = 1;
p.rotation = 0;
p.next = NULL;
for(int i=1;i<=n;i++){
p.pid = i;
cin>>p.need_cpu>>p.occupy_num;
readyqueue_roation.push(p);
}
rotation_ctrl();
}
return 0;
}
结果展示
以三个进程为例
1.优先数法
2.简单轮转法
小结
操作系统真的是我学过最最难的一门课了。完成这一些代码,我也是在广泛查阅资料,询问同学后才完成的。(摊手)认真写过这段代码(起码看过)之后,对进程的调度一定会有新的认识。因此希望大家看到这篇文章,不要一味的复制粘贴,真正弄懂才是最重要的。