操作系统自学 系统调度算法(了解)
2013-11-12 22:29
260 查看
各系统中的调度算法
一、批处理系统中的调度1、先来先服务调度
在所有算法中,最简单的是非抢占式的“先来先服务”算法,进程按照他们请求CPU的顺序使用CPU
这个算法的主要有点是易于理解并且便于使用,对于排队的进程而言也是公平的,在这个算法中,一个单链表记录了所有的就绪进程,十分易于实现
但是这个算法有一个明显的缺点,很有可能让CPU密集型进程或者IO密集型进程集中执行,这样,资源利用率会大幅下降,且短进程常常需要消耗大量的时间等待长进程的完成
2、最短作业优先
这个算法适用于运行时间可以预知的进程调度,例如,保险公司因为每天都做类似的工作,所以人们可以相当精确的预测处理1000个索赔的一批作业需要多少时间,由于最短作业优先运行,后续进程的等待时间就会是最短的,平均周转时间就会是最低的
但是,对于并非所有作业都是同时运行的情况,这个调度算法是不适用的,因为最短的作业可能还没有到达
3、最短剩余时间优先
对于并非所有作业都同时运行的情况,如果新到达的作业的运行时间低于当前运行程序的剩余时间,那么就先挂起当前进程,而运行该新进程
这个算法可以使得新的短进程得到良好的服务
与最短作业优先算法一样,只适用于运行时间可以提前掌握的情况
二、交互式系统中的调度
1、轮转调度
最古老、最简单、最公平并且使用最广泛的算法就是“轮转调度”算法
每个进程被分配一个时间段,称为“时间片”,即允许该进程在该时间段内运行,如果在时间片结束时,该进程仍在运行,将剥夺CPU分配给另一个就绪的进程,如果进程提前结束,那么调度程序会立即调度新的就绪进程
时间片轮转很容易实现,只要维护一张可运行进程列表,当一个进程用完他的时间片后,将其移到队列末尾即可,如图所示:
![](http://c.hiphotos.baidu.com/album/pic/item/d833c895d143ad4bfba4b2cf83025aafa40f0632.jpg)
从一个进程切换到另一个进程需要处理很多事务:保存和装入寄存器值以及内存映像、更新各种表哥和列表、清除和重新调入内存高速缓存等,一般称为“进程切换”,有时也称为“上下文切换”,切换往往会耗费大量的CPU时间
因此,如果设置的时间片太短,会导致过多的进程切换降低CPU效率,而设置过长的时间片有会引起端的交互请求响应时间变长(极端的例子就是从抢占式调度算法变成了非抢占式调度算法),一般来说将时间片设置为20 - 50ms是比较合理的
2、优先级调度
轮转调度的隐含假设是:所有的进程同等重要
而事实上,进程常常是由优先级的,这就导致了优先级调度:每个进程都被赋予一个优先级,允许优先级最高的可运行进程先运行,例如在PC机上,交互式进程常常比后台进程要重要,因此被赋予更高的优先级
为了防止高优先级的进程无休止的执行下去,调度进程可以在每个时钟滴答降低当前进程的优先级,如果这个动作导致当前进程优先级低于某个进程,那么就进行进程切换
在UNIX中,有一条命令nice,可以允许用户自愿降低自己进程的优先级,但从未有人用过它
为达到某种目的,优先级可以由系统动态确定也是允许的
如果不偶尔对优先级进行调整,则的优先级进程很可能会产生饥饿现象
3、多级队列
由于设置常时间片比频繁进行进程切换要高效的多,但是长时间片又会影响到系统的响应时间,所以,分级赋予不同长度的时间片就是一个好的方法,如对于最高优先级的进程运行1个时间片,对于次高优先级的进程运行2个时间片,以此类推,每当一个进程用完分配的时间片后,他就被移到下一类
这样,随着进程优先级的不断降低,他的获得时间片数量增长的同时运行频度则会逐渐放慢,从而为短的交互进程让出CPU
对于那些刚开始运行很长一段时间后才开始进行交互的进程,如终端,为了防止其永远处于被惩罚状态,可以才去下面的策略:
只要终端上有回车键按下,则这个终端的所有进程就都被移动到最高优先级,这样做的原因是假设此时进程即将需要交互。但是盲目的使用这种方案可能会使得某些用户为了提高优先级而刻意使用回车,这当然是不希望看到的,而同时,后台进程也有可能永远都得不到运行
这样做常常可以讨好交互用户和进程,但却牺牲了后台进程
4、最短进程有限
交互式进程通常遵循下列模式:等待命令、执行命令、等待命令、执行命令 。。。不断反复
我们也可以把每个命令的执行看作是一个作业,通过优先运行最短作业来使得响应时间最短,这里的关键问题就是系统如何预测一个进程的期望运行时间
一个很有效的方法是根据进程过去的行为推测,有一种老化算法:
如最早的一次程序执行时间为T0,之后的一次执行时间为T1,再之后的一次为T2。。。,那么,就可以得到如下队列:
T0,T0/2+T1/2,T0/4+T1/4+T2/2,T0/8+T1/8+T2/4+T3/2,。。。
这样,先前的估计量的权值会越来越小,这种技术就被称为“老化”
5、保证调度
一种完全不同的调度算法是向用户作出明确的性能保证,然后去实现它
一种很实际并很容易实现的保证是:若用户工作时有n个用户登录,则用户将获得CPU处理能力的1/n,类似的,在一个有n个进程运行的单用户系统中,每个进程都获得1/n的CPU时间
这样看起来足够公平
6、彩票调度
保证调度很难实现,有另一个类似但是十分容易实现的调度算法就是“彩票调度”
彩票调度的基本思想是向进程提供各种系统资源(如CPU时间)的彩票,一旦需要作出一项调度决策时,就随机抽出一张彩票,拥有该彩票的进程获得该资源,比如系统可以掌握每秒50次的一种彩票,作为奖励,每个获奖者可以获得20ms的CPU时间
彩票调度是比较公平的,并且是反应迅速的,因为拥有较大份额彩票的进程会有更大的机会获得资源
对于阻塞程序,它可以把彩票还给系统,之后在阻塞结束后,系统再把彩票还给他,他就可以继续运行了
彩票调度可以用来解决其他方法很难解决的问题,比如一个视频服务器,在该服务器上若干进程正在向其用户提供视频流,每个视频流帧率都不同,假设他们分别是10、20和25帧/秒,如果给这些进程分别分配10、20和25张彩票,他们会自动地按照大致正确的比例划分CPU使用
7、公平分享制度
到目前为止的所有调度方法都有一个共同的缺陷,那就是并不关注进程的所有者,比如用户1启动了9个进程,用户2只启动了1个进程,那么用户1将获得90%的CPU
为了避免这个情况,某些系统在调度处理之前考虑谁拥有进程这一因素,每个用户分配到CPU时间的一部分,而调度程序以一种强制的方式选择进程
三、实时系统中的调度
实时系统是一种时间起着主导作用的系统
典型的,外部的一种或多种物理设备给了计算机一个刺激,而计算机必须在一个确定的时间范围内恰当的反应
比如CD播放器必须在非常短的时间内将驱动器中的位流转换为音乐,否则音乐听起来就会有异常
实时系统通常可以分为“硬实时”和“软实时”
硬实时指必须满足绝对的截止时间,而后者可以允许偶尔的错失截止时间
在这两种情形中,实时系统都是通过将程序划分为一组进程而实现的,其中每个进程的行为是可预测和提前预知的,这些进程一般寿命很短,并且极快的完成
实时系统的事件按照响应方式进一步分类为周期性事件和非周期性时间,一个系统可能要响应多个周期性事件流
实时系统的调度算法可以是静态的或者动态的,前者在系统开始运行前作出调度决策,后者在运行过程中进行调度决策,只有 在可以提前掌握所完成的工作以及必须满足截止时间等全部信息时,静态调度算法才能工作
下面代码转载自新浪微博。
操作系统系统调度算法。
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
const int Maxnum = 101;
typedef struct information
{
int in_time;//进入时间
int use_time;//估计花费时间
int job;//job编号
int start,finish,Ti;//开始工作时间 完成作业时间 周转时间
int flag;//优先级别 用户自己设置
double Wi;//带权周转时间
double Ri;//最高响应比
information()
{
start = flag = Ti = finish = 0;
Ri = Wi = 0.0;
}
}node;
struct node1//此结构体用于优先级算法的抢占式
{
friend bool operator < (node1 n1, node1 n2)//优先队列中的比较规则 即由小到大
{
return n1.priority > n2.priority;
}
int priority;
int pos;
};
struct node2//此结构体用于最短作业优先算法的抢占式
{
friend bool operator < (node2 n1, node2 n2)//优先队列中的比较规则 即由小到大
{
return n1.priority > n2.priority;
}
int priority;
int pos;
};
node slove_node[Maxnum];
node Main_node[Maxnum];
bool finish_flag[Maxnum];//确定一个作业是否做完
int num;
string Int_to_String(int Time);
void FCFS();
void Rotate();
void Priority();
void Short();
void HRN();
void print();
int cmp( const void *a ,const void *B)
{
return (*(information *)a).in_time >= (*(information *)B).in_time ? 1 : -1;
}
int main()
{
int i;
cout<<"请输入现在总共有多少个作业要做(n<=100)"<<endl;
cin>>num;
cout<<"请输入各个作业的进入工作的开始时间和估计执行完需要的时间"<<endl;
string start_time;
int Int_start_time;
int need_time;
for (i = 0;i<num;i++)
{
cin>>start_time>>need_time;
int len = start_time.length();
if (len == 4)
Int_start_time = (start_time[0] - '0')*60 + (start_time[2] - '0')*10 + start_time[3] - '0';
if (len == 5)
Int_start_time = ((start_time[0] - '0')*10 + (start_time[1] - '0'))*60 + (start_time[3] - '0')*10 + start_time[4] - '0';
Main_node[i].job = i+1;
Main_node[i].in_time = Int_start_time;
Main_node[i].use_time = need_time;
}
qsort(Main_node,num,sizeof(Main_node[0]),cmp);
while(1)
{
int choose;
cout<<"——请输入你想进行操作的算法——"<<endl;
cout<<"1: 先来先服务算法"<<endl;
cout<<"2: 轮转算法"<<endl;
cout<<"3: 优先级算法"<<endl;
cout<<"4: 最短作业优先算法"<<endl;
cout<<"5:最高响应比优先算法"<<endl;
cout<<"0: 退出系统"<<endl;
cout<<"————————————————"<<endl;
cin>>choose;
switch (choose)
{
case 1:
FCFS();//先来先服务算法
break;
case 2:
Rotate();//轮转算法
break;
case 3:
Priority();//优先级算法
break;
case 4:
Short();//最短作业优先算法
break;
case 5:
HRN();//最高响应比优先算法
break;
case 0:
exit(0);
break;
}
}
return 0;
}
//////////////////////////////////////////////////////////////
void FCFS()
{
int i,j;
for (j = 0;j<num;j++)
{//这里对所要处理的结构体数组和main函数中输入的数据进行赋值以便后面进行处理
slove_node[j].use_time = Main_node[j].use_time;
slove_node[j].job = Main_node[j].job;
slove_node[j].in_time = Main_node[j].in_time;
}//
i = 0;
int temp_time = 0;//时间流程的控制变量
while(i<num)
{
if(temp_time<slove_node[i].in_time)//如果做完一个作业第二个作业还没有到
{
temp_time = slove_node[i].use_time+slove_node[i].in_time;
slove_node[i].finish = temp_time;
slove_node[i].Ti = slove_node[i].finish - slove_node[i].in_time;//计算这个作业开始的时间
slove_node[i].start = slove_node[i].finish - slove_node[i].use_time;
slove_node[i].Wi = (double)slove_node[i].Ti/slove_node[i].use_time;
} //这种情况除第一次外应该要避免
else
{
temp_time +=slove_node[i].use_time;
slove_node[i].finish = temp_time;
slove_node[i].start = slove_node[i].finish - slove_node[i].use_time;
slove_node[i].Ti = slove_node[i].finish - slove_node[i].in_time;
slove_node[i].Wi = (double)slove_node[i].Ti/slove_node[i].use_time;
}
i++;
}
print();
}
//////////////////////////////////////////////////////////////
void Rotate()
{
memset(finish_flag,0,sizeof(finish_flag));
bool in_que_flag[Maxnum],first_out[Maxnum];//标记作业进如队列 和 标记作业第一次出队列
memset(in_que_flag,0,sizeof(in_que_flag));
memset(first_out,0,sizeof(first_out));
int use_time[Maxnum];//用临时的时间还判断作业是否做完
int rotate_time,i,j;//轮转时间
for (j = 0;j<num;j++)
{
use_time[j] = slove_node[j].use_time = Main_node[j].use_time;
slove_node[j].job = Main_node[j].job;
slove_node[j].in_time = Main_node[j].in_time;
}
cout<<"请设置轮转时间:";
cin>>rotate_time;
queue<int> q; //队列q用于作业在等待状态
while(!q.empty())
q.pop();
int get;
bool flag = true;
int temp_time = 0;
while(flag)
{
flag = false;
for(i = 0;i < num; i++)
{
if(!finish_flag[i])//判断是否还有作业没有做的
{
q.push(i);
in_que_flag[i] = true;
first_out[i] = true;
flag = true;
if (temp_time < slove_node[i].in_time)//如果当前时间比第i个作业进入时间都小
{
temp_time = slove_node[i].in_time;
}
break;
}
}
if (!flag)
break;
while (!q.empty())
{
get = q.front();
for (j = 0;j<num;j++)
{
if (first_out[j])
{
slove_node[j].start = temp_time;//计算开始做这个作业的时间
first_out[j] = false;
}
}
q.pop();//做一个时间片出一次队列
temp_time += rotate_time;
use_time[get] -= rotate_time;
for (j = 0;j<num;j++)
{
if (!in_que_flag[j]&& temp_time >= slove_node[j].in_time)//判断还没有进入队列,并且所处的时间正好大于或者等于下一个作业开始的时间
{
q.push(j);
first_out[j] = true;
in_que_flag[j] = true;
}
}
if (use_time[get] <= 0)//表示已经做完一个作业
{
finish_flag[get] = true;
slove_node[get].finish = temp_time;
slove_node[get].Ti = slove_node[get].finish - slove_node[get].in_time;
slove_node[get].Wi = (double)slove_node[get].Ti/slove_node[get].use_time;
}
else
q.push(get);//循环的进入队列,直到已经做完
}
}
print();
}
//////////////////////////////////////////////////////////////
void Priority()
{
int choose;//是否选择抢占式的标记
int i,j;
for (i = 0;i<num;i++)
{
slove_node[i].use_time = Main_node[i].use_time;
slove_node[i].job = Main_node[i].job;
slove_node[i].in_time = Main_node[i].in_time;
}
cout<<"请输入这"<<num<<"个作业的优先级"<<endl;
for (i = 0;i<num;i++)
{
cout<<"请输入作业"<<slove_node[i].job<<"的优先级"<<endl;
cin>>slove_node[i].flag;//设置作业的优先级
}
cout<<"请选择是否使用抢占式(1(代表抢占)0(代表不能抢占))"<<endl;
cin>>choose;
if (choose == 0)/////////////////////////////////////////////////////非抢占式
{
bool flag_will[Maxnum];//判断一个作业做完之后其他有多少作业可以开始做了
memset(flag_will,0,sizeof(flag_will));
memset(finish_flag,0,sizeof(finish_flag));
bool flag = true;// while的控制变量
int temp_time = 0 ;
int min_j = num;
slove_node[min_j].flag = INT_MAX;
while(flag)
{
flag = false;
for(i = 0;i < num; i++)
{
if(!finish_flag[i])//判断是否还有作业没有做的
{
// cout<<i<<endl;
flag = true;
if (temp_time < slove_node[i].in_time)//如果当前时间比第i个作业进入时间都小
{
temp_time = slove_node[i].in_time;
flag_will[i] = true;
}
break;
}
}
if (!flag)
break;
for (j = 0;j<num;j++)
{
if (flag_will[j])
{
if (slove_node[j].flag<slove_node[min_j].flag)//级别越高flag的值越小
min_j = j;
}
}
temp_time += slove_node[min_j].use_time;
// cout<<temp_time<<endl;
for (i = 0;i<num;i++)
{
if (!finish_flag[i] && temp_time>=slove_node[i].in_time)
flag_will[i] = true;
}
slove_node[min_j].finish = temp_time;
slove_node[min_j].start = slove_node[min_j].finish - slove_node[min_j].use_time;
slove_node[min_j].Ti = slove_node[min_j].finish - slove_node[min_j].in_time;
slove_node[min_j].Wi = (double)slove_node[min_j].Ti/slove_node[min_j].use_time;
flag_will[min_j] = false;
finish_flag[min_j] = true;
slove_node[min_j].flag = INT_MAX;
}
print();
}
else////////////////////////////////////////////333333333333333333333333抢占式
{
node1 temp[Maxnum];
for (i = 0;i<num;i++)
{
temp[i].priority = slove_node[i].flag;
temp[i].pos = i;
}
bool in_que_flag[Maxnum],first_out[Maxnum];//标记作业进入队列 和 标记作业第一次出队列
memset(finish_flag,0,sizeof(finish_flag));
memset(in_que_flag,0,sizeof(in_que_flag));
memset(first_out,0,sizeof(first_out));
int use_time[Maxnum];//用临时的时间还判断作业是否做完
for (i = 0;i<num;i++)
{
use_time[i] = slove_node[i].use_time;
}
priority_queue<node1> pri_q;
while (!pri_q.empty())//优先队列 用于处理作业的优先级
{
pri_q.pop();
}
node1 get;
bool flag = true;
int first_temp_time;
int temp_time=0;
while(flag)
{
flag = false;
for(i = 0;i < num; i++)
{
if(!finish_flag[i])//判断是否还有作业没有做的
{
pri_q.push(temp[i]);
in_que_flag[i] = true;
first_out[i] = true;
flag = true;
if (temp_time < slove_node[i].in_time)//如果当前时间比第i个作业进入时间都小
{
temp_time = slove_node[i].in_time;
}
break;
}
}
if (!flag)
break;
while (!pri_q.empty())
{
int while_flag = 3;//进行循环 总共只有三种情况
bool metex = false;//设置一个互斥量,如果while_flag已经等于1了就不做让while_flag等于2的操作
get = pri_q.top();
for (j = 0;j<num;j++)
{
if (first_out[j])
{
slove_node[j].start = temp_time;//计算开始做这个作业的时间
first_out[j] = false;
}
}
pri_q.pop();//做一个时间片出一次队列
if (get.pos < num -1)
{
if (!in_que_flag[get.pos + 1] && slove_node[get.pos].flag > slove_node[get.pos + 1].flag
&&temp_time + use_time[get.pos] >= slove_node[get.pos+1].in_time )
//判断get.pos之后有没有满足
//1,从来还没有进过优先队列
//2,当前的优先级比后一个优先级低,
//3,当前时间加上做完当前作业的时间比后一个开始进入时间大于或者等于
// 这个三个条件同时满足才做后面的事情
{
pri_q.push(temp[get.pos+1]);
first_temp_time = temp_time;
temp_time += slove_node[get.pos + 1].in_time - first_temp_time;
use_time[get.pos] -= slove_node[get.pos + 1].in_time - first_temp_time;
in_que_flag[get.pos+1] = true;
first_out[get.pos+1] = true;
while_flag = 1;
metex = true;
}
}
if (!metex)
{
for (i = 0;i<num;i++)
{
if (!finish_flag[get.pos] && !in_que_flag[i] && temp_time + use_time[get.pos] >= slove_node[i].in_time
&& temp[get.pos].priority > slove_node[i].flag)
//当get.pos满足
//1.当前作业还没做完
//2、第i个作业还没有进入过队列
//3、当前作业的剩余时间加上当前时间 大于或者等于 第i个作业的进入时间
//4、当前作业的优先级比第i个作业的优先级要低
{
if (temp_time>slove_node[i].in_time) //当当前时间已经大于第i个作业的进入时间时
{
pri_q.push(temp[i]);
slove_node[i].start = temp_time;
in_que_flag[i] = true;
first_out[i] = true;
while_flag = 2;
break;
}
else
{
pri_q.push(temp[i]);
use_time[get.pos] -= slove_node[i].in_time - temp_time;
temp_time = slove_node[i].in_time;
slove_node[i].start = temp_time;
in_que_flag[i] = true;
first_out[i] = true;
while_flag = 2;
break;
}
}
}
}
if (while_flag == 3)
//如果不满足上面的两条约束,那么当前作业是优先级最高的
{
temp_time += use_time[get.pos];
use_time[get.pos] = 0;
}
if (use_time[get.pos] <= 0)//表示已经做完一个作业
{
finish_flag[get.pos] = true;
slove_node[get.pos].finish = temp_time;
slove_node[get.pos].Ti = slove_node[get.pos].finish - slove_node[get.pos].in_time;
slove_node[get.pos].Wi = (double)slove_node[get.pos].Ti/slove_node[get.pos].use_time;
}
else
pri_q.push(get);//循环的进入队列,直到已经做完
}
}
print();
}
}
//////////////////////////////////////////////////////////////
void Short()
{
int i,j;
for (i = 0;i<num;i++)
{
slove_node[i].use_time = Main_node[i].use_time;
slove_node[i].job = Main_node[i].job;
slove_node[i].in_time = Main_node[i].in_time;
}
int choose;//是否选择抢占式的标记
cout<<"请选择是否使用抢占式(1(代表抢占)0(代表不能抢占))"<<endl;
cin>>choose;
if (choose == 0)
{
bool flag_will[Maxnum];//判断一个作业做完之后其他有多少作业可以开始做了
memset(flag_will,0,sizeof(flag_will));
memset(finish_flag,0,sizeof(finish_flag));
bool flag = true;
int temp_time=0 ;
int min_j = num;//定义一个变量 用于和已经进来的作业进行比较把最短时间的找出来 初始化为最大的
slove_node[min_j].use_time = INT_MAX;//找最小的就初始化为最大的,用于比较和交换
while(flag)
{
// bool mutex = false;
flag = false;
for(i = 0;i < num; i++)
{
if(!finish_flag[i])//判断是否还有作业没有做的
{
flag = true;
if (temp_time < slove_node[i].in_time)//如果当前时间比第i个作业进入时间都小
{
temp_time = slove_node[i].in_time;
flag_will[i] = true;
}
break;
}
}
if(!flag)
break;
for (j = 0;j<num;j++)//这里找出能够进来的所有作业最小的
{
if (flag_will[j])
{
if (slove_node[j].use_time<slove_node[min_j].use_time)
min_j = j;//最小的标号就为min_j
}
}
temp_time += slove_node[min_j].use_time;
for (i = 0;i<num;i++)//找出作业满足当前时间大于作业的进入时间
{
if (!finish_flag[i] && temp_time>=slove_node[i].in_time)
{
flag_will[i] = true;
// mutex = true;
}
}
slove_node[min_j].finish = temp_time;
slove_node[min_j].start = slove_node[min_j].finish - slove_node[min_j].use_time;
slove_node[min_j].Ti = slove_node[min_j].finish - slove_node[min_j].in_time;
slove_node[min_j].Wi = (double)slove_node[min_j].Ti/slove_node[min_j].use_time;
// flag_will[min_j] = false;
finish_flag[min_j] = true;
slove_node[min_j].use_time = INT_MAX;//这里很重要要重新重置为最大数
}
print();
}
else////////////////////////////////////////////4444444444444444444444444444444444抢占式
{
node2 temp[Maxnum];
for (i = 0;i<num;i++)
{
temp[i].priority = slove_node[i].use_time;
temp[i].pos = i;
}
bool in_que_flag[Maxnum],first_out[Maxnum];//标记作业进入队列 和 标记作业第一次出队列
memset(finish_flag,0,sizeof(finish_flag));
memset(in_que_flag,0,sizeof(in_que_flag));
memset(first_out,0,sizeof(first_out));
int use_time[Maxnum];//用临时的时间还判断作业是否做完
for (i = 0;i<num;i++)
{
use_time[i] = slove_node[i].use_time;
}
priority_queue<node2> pri_q;
while (!pri_q.empty())//优先队列 用于处理作业的优先级
{
pri_q.pop();
}
node2 get;
bool flag = true;
int first_temp_time;
int temp_time = 0;
while(flag)
{
flag = false;
for(i = 0;i < num; i++)
{
if(!finish_flag[i])//判断是否还有作业没有做的
{
pri_q.push(temp[i]);
in_que_flag[i] = true;
first_out[i] = true;
if (temp_time < slove_node[i].in_time)//如果当前时间比第i个作业进入时间都小
{
temp_time = slove_node[i].in_time;
}
flag = true;
break;
}
}
if (!flag)
break;
while (!pri_q.empty())
{
int while_flag = 3;
bool metex = false;
get = pri_q.top();
for (j = 0;j<num;j++)
{
if (first_out[j])
{
slove_node[j].start = temp_time;//计算开始做这个作业的时间
first_out[j] = false;
}
}
pri_q.pop();//做一个时间片出一次队列
if (get.pos < num -1)
{
if (!in_que_flag[get.pos + 1] &&
(use_time[get.pos] - (slove_node[get.pos + 1].in_time - slove_node[get.pos].in_time)) > use_time[get.pos + 1]
&&temp_time + use_time[get.pos] >= slove_node[get.pos+1].in_time )
//判断get.pos之后有没有满足
//1,后一个作业从来还没有进过优先队列
//2,当前的优先级比后一个优先级低,
//3,当前时间加上做完当前作业的时间比后一个开始进入时间大于或者等于
{
temp[get.pos].priority -= slove_node[get.pos + 1].in_time - slove_node[get.pos].in_time;
pri_q.push(temp[get.pos+1]);
first_temp_time = temp_time;
temp_time += slove_node[get.pos + 1].in_time - first_temp_time;
use_time[get.pos] -= slove_node[get.pos + 1].in_time - first_temp_time;
in_que_flag[get.pos+1] = true;
first_out[get.pos+1] = true;
while_flag = 1;
metex = true;
//cout<<"1:"<<temp_time<<endl;
// cout<<"1:"<<get.pos<<" "<<use_time[get.pos]<<endl;
}
}
if (!metex)
{
for (i = 0;i<num;i++)
{
if (!finish_flag[get.pos] && !in_que_flag[i] && temp_time + use_time[get.pos] >= slove_node[i].in_time
&& (use_time[get.pos] - (slove_node[i].in_time - temp_time)) > slove_node[i].use_time)
//当get.pos满足
//1、当前作业还没做完
//2、第i个作业还没有进入过队列
//3、当前作业的剩余时间加上当前时间 大于或者等于 第i个作业的进入时间
//4、当前作业的优先级比第i个作业的优先级要低
{
if (temp_time>slove_node[i].in_time)//当当前时间已经大于第i个作业的进入时间时
{
pri_q.push(temp[i]);
slove_node[i].start = temp_time;//计算开始做这个作业的时间
in_que_flag[i] = true;
while_flag = 2;
// cout<<"2:"<<temp_time<<endl;
// cout<<"2:"<<get.pos<<" "<<use_time[get.pos]<<endl;
break;
}
else
{
temp[get.pos].priority -= slove_node[i].in_time - temp_time;
pri_q.push(temp[i]);
use_time[get.pos] -= slove_node[i].in_time - temp_time;
temp_time = slove_node[i].in_time;
slove_node[i].start = temp_time;//计算开始做这个作业的时间
in_que_flag[i] = true;
while_flag = 2;
// cout<<"2:"<<temp_time<<endl;
// cout<<"2:"<<get.pos<<" "<<use_time[get.pos]<<endl;
break;
}
}
}
}
if (while_flag == 3)
//如果不满足上面的两条约束,那么当前作业是优先级最高的
{
temp_time += use_time[get.pos];
use_time[get.pos] = 0;
// cout<<"3:"<<temp_time<<endl;
//cout<<"3:"<<get.pos<<" "<<use_time[get.pos]<<endl;
}
if (use_time[get.pos] <= 0)//表示已经做完一个作业
{
finish_flag[get.pos] = true;
slove_node[get.pos].finish = temp_time;
slove_node[get.pos].Ti = slove_node[get.pos].finish - slove_node[get.pos].in_time;
slove_node[get.pos].Wi = (double)slove_node[get.pos].Ti/slove_node[get.pos].use_time;
}
else
pri_q.push(get);//循环的进入队列,直到已经做完
}
}
print();
}
}
/////////////////////////////////////////////////////////////////////////////////////////
void HRN()
{
int i,j;
for (i = 0;i<num;i++)
{
slove_node[i].use_time = Main_node[i].use_time;
slove_node[i].job = Main_node[i].job;
slove_node[i].in_time = Main_node[i].in_time;
}
// int choose;//是否选择抢占式的标记
// cout<<"请选择是否使用抢占式(1(代表抢占)0(代表不能抢占))"<<endl;
// cin>>choose;
// if (choose == 0)
// {
bool flag_will[Maxnum];//判断一个作业做完之后其他有多少作业可以开始做了
memset(flag_will,0,sizeof(flag_will));
memset(finish_flag,0,sizeof(finish_flag));
bool flag = true;
int temp_time = 0;
// cout<<slove_node[0].use_time<<endl;
int min_j = num;
slove_node[min_j].Ri = 0;
while(flag)
{
flag = false;
for(i = 0;i < num; i++)
{
if(!finish_flag[i])//判断是否还有作业没有做的
{
flag = true;
if (temp_time < slove_node[i].in_time)//如果当前时间比第i个作业进入时间都小
{
temp_time = slove_node[i].in_time;
flag_will[i] = true;
}
break;
}
}
if(!flag)
break;
for (j = 0;j<num;j++)
{
if (flag_will[j])
{
slove_node[j].Ri = 1 + (temp_time - slove_node[j].in_time)/slove_node[j].use_time;//计算响应比
if (slove_node[j].Ri > slove_node[min_j].Ri)
min_j = j;
}
}
temp_time += slove_node[min_j].use_time;
for (i = 0;i<num;i++)
{
if (!finish_flag[i] && temp_time>=slove_node[i].in_time)
flag_will[i] = true;
}
slove_node[min_j].finish = temp_time;
slove_node[min_j].start = slove_node[min_j].finish - slove_node[min_j].use_time;
slove_node[min_j].Ti = slove_node[min_j].finish - slove_node[min_j].in_time;
slove_node[min_j].Wi = (double)slove_node[min_j].Ti/slove_node[min_j].use_time;
flag_will[min_j] = false;
finish_flag[min_j] = true;
slove_node[min_j].Ri = 0;
}
print();
}
//////////////////////////////////////////////////////////////
void print()
{
int j;
double per_Ti, per_Wi,temp1,temp2;
temp1 = temp2 = 0.0;
for(j = 0;j<num;j++)
{
temp1 += slove_node[j].Ti;
temp2 += slove_node[j].Wi;
}
per_Wi = temp2/num;
per_Ti = temp1/num;
//cout<<endl;
for(j = 0;j<num;j++)
{
cout<<"作业"<<slove_node[j].job<<":进入时间:"<<Int_to_String(Main_node[j].in_time)<<"\t估计运行时间:"<<Main_node[j].use_time
<<"\n开始时间:"<<Int_to_String(slove_node[j].start)<<"\t完成时间:"<<Int_to_String(slove_node[j].finish)<<"\t周转时间:"
<<slove_node[j].Ti<<"\t带权周转时间:"<<slove_node[j].Wi<<endl;
}
cout<<"平均周转时间:"<<per_Ti<<"\t平均带权周转时间:"<<per_Wi<<endl;
//cout<<endl;
}
string Int_to_String(int Time)//时间的转换
{
string result_finally;
char result[6];
int hour;
int minute;
Time = Time40;
hour = Time/60;
minute = Time`;
if (hour >= 10)
{
result[0] = hour/10 +'0';
result[1] = hour + '0';
result[2] = ':';
if (minute>=10)
{
result[3] = minute/10 +'0';
result[4] = minute + '0';
}
else
{
result[3] = '0';
result[4] = minute + '0';
}
result[5] = '\0';
}
else
{
result[0] = hour +'0';
result[1] = ':';
if (minute>=10)
{
result[2] = minute/10 +'0';
result[3] = minute + '0';
}
else
{
result[2] = '0';
result[3] = minute + '0';
}
result[4] = '\0';
}
result_finally = result;
return result_finally;
}
相关文章推荐
- (1)操作系统分类,常用的系统调度算法。
- 操作系统---OS的进程调度算法
- 操作系统进程调度算法(Java 实现)
- 操作系统处理器调度(CPU调度)的学习以及批处理系统中采用的调度算法、交互式系统中采用的调度算法
- 了解下除国外的windows,linux,mac系统,看下国内的操作系统
- 计算机操作系统-进程的调度算法
- c++模拟操作系统进程调度算法(优先数,时间片轮转)
- LMT NEW PBS作业排队计算系统的调度算法
- 操作系统中常用的进程调度算法
- 几个常用的操作系统进程调度算法
- 操作系统调度算法之-优先数高者优先算法
- 文件系统 和 操作系统的调度器 --- 一点想法
- 操作系统——使用动态优先权的进程调度算法的模拟
- 操作系统进程调度算法(Java 实现)
- 操作系统处理器调度(CPU调度)的学习以及批处理系统中采用的调度算法、交互式系统中采用的调度算法
- 操作系统调度算法分析
- 操作系统进程调度算法 先到先服务 短作业 优先级 时间片轮转
- 几个常用的操作系统进程调度算法
- 操作系统进程调度算法(Java 实现)
- 操作系统处理器调度(CPU调度)的学习以及批处理系统中采用的调度算法、交互式系统中采用的调度算法