目录
一 ,先来先服务的调度算法
1.1 优缺点
二,最短作业优先算法SJF
2.1 SJF算法的优缺点:
2.2 SJF调度算法的问题:
三,高优先级调度算法
3.1 优先级调度的含义
3.2 调度算法的两种方式
3.3 优先级的类型
3.4 静态优先级
3.5 动态优先级
最简单的调度算法,既可以用于作业调度 ,也可以用于程序调度,当作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”,直到该进程运行到完成或发生某事件堵塞后,进程调度程序才将处理机分配给其他进程。
有利于长作业(进程)而不利于短作业(进程)
有利于CPU繁忙型作业(进程)而不利于I/O繁忙型作业(进程)
#include "pch.h"
#include
using namespace std;
int main()
{
int countHomework;
cout << "请输入作业数量:" << endl;
cin >> countHomework;
double **arr = new double *[countHomework];
for (int i = 0;i < countHomework;i++)
{
arr[i] = new double[5];
}
for (int i = 0;i < countHomework;i++)//初始化
for (int j = 0;j < 5;j++)
arr[i][j] = 0;
double starttime, endtime;
cout << "请输入开始时间和运行时间" << endl;
for (int i = 0;i < countHomework;i++) {
cin >> starttime >> endtime;
arr[i][1] = starttime;
arr[i][2] = endtime;
}
double temp_1;
double temp_2;
for (int i = 0;i < countHomework;i++)
{
for (int j = i + 1;j < countHomework;j++)
{
if (arr[i][1] > arr[j][1])
{
temp_1 = arr[i][1];
temp_2 = arr[i][2];
arr[i][1] = arr[j][1];
arr[i][2] = arr[j][2];
arr[j][1] = temp_1;
arr[j][2] = temp_2;
}
}
}
double currentTime;
currentTime = arr[0][1];
arr[0][3] = currentTime+arr[0][2];
currentTime = arr[0][3];
arr[0][4] = currentTime-arr[0][1];
for (int i = 1;i < countHomework;i++)
{
arr[i][3] = currentTime + arr[i][2];
currentTime += arr[i][2];
arr[i][4] = currentTime - arr[i][1];//计算周转时间
}
cout << "进程号\t" << "开始时间\t" << "运行时间\t" << "周转时间\t" << endl;
for (int i = 0;i < countHomework;i++) {
arr[i][0] = i + 1;
for (int j = 0;j < 5;j++)
{
cout << arr[i][j] << "\t";
}
cout << endl;
}
}
SJF算法以进入系统的作业所要求的CPU时间为标准,是指对短作业或者短进程优先调度的算法,将每个进程与其估计运行时间进行关联选取估计计算时间最短的作业投入运行。
算法易于实现。但效率不高,主要弱点是忽视了作业等待时间;会出现饥饿现象。
SJF算法与FCFS算法的比较:
SJF的平均作业waiting time比FCFS要小,故它的调度性能比FCFS好。
实现SJF调度算法需要知道作业所需运行时间,否则调度就没有依据,要精确知道一个作业的运行时间是办不到的。
SJF是一种Non-preemptive(非抢占试)调度。
与SJF类似的一种preemptive 版本的调度叫shortest-remaining-time-first。
SJF是一种优先调度(priority scheduling),优先的是inverse of 预测的下一个中央处理器突发时间。
SJF调度算法是被证明了的最佳调度算法,这是因为对于给定的一组进程,SJF算法的平均周转时间最小。通过将短进程移到长进程之前,短进程等待时间的减少大于长进程等特时间的增加,因此,平均等特时间减少了。
#include"pch.h"
#include
using namespace std;
int main()
{
int jobNum = 0;
cout << "请输入作业数量" << endl;
cin >> jobNum;
double **arr = new double*[jobNum];
for (int i = 0;i < jobNum;i++)
{
arr[i] = new double[5];
}
for (int i = 0;i < jobNum;i++)
for (int j = 0;j < 5;j++)
arr[i][j] = 0;
double startTime = 0, runningTime = 0;
cout << "请输入开始时间和运行时间" << endl;
for (int i = 0;i < jobNum;i++)
{
cin >> startTime >> runningTime;
arr[i][1] = startTime;
arr[i][2] = runningTime;
arr[i][0] = 0;
}
double currentTime = arr[0][1];
arr[0][3] = arr[0][1] + arr[0][2];
currentTime = arr[0][3];
arr[0][4] = currentTime - arr[0][1];
cout << currentTime << endl; arr[0][0] = 1;
int count = 1;
double priority = 0;//定义优先级
while (count < jobNum)
{
int i_job = 0;
double maxPriority = 0;
for (int i = 1;i < jobNum ;i++)
{
if ((arr[i][0] != 1) && (arr[i][1] < currentTime)) {
priority = (currentTime - arr[i][1] + arr[i][2]) / (arr[i][2]);//求出优先级
if (maxPriority < priority) {
maxPriority = priority;
i_job = i;
}
}
}
arr[i_job][3] = arr[i_job][2]+currentTime;
currentTime += arr[i_job][2];
arr[i_job][4] = currentTime - arr[i_job][1];/
arr[i_job][0] = 1;
count++;
}
cout << "作业号\t" << "开始时间\t" << "运行时间\t" << "结束时间\t" << "周转时间" << "\t" << endl;
for (int i = 0;i < jobNum;i++)
{
arr[i][0] = i + 1;
cout << arr[i][0] << "\t\t" << arr[i][1] << "\t\t" << arr[i][2] << "\t\t" << arr[i][3] << "\t\t" << arr[i][4] << "\t\t" << endl;
}
}
(1)当该算法用于作业调度时,系统从后备作业队列中选择若干个优先级最高的,且系统能满足资源要求的作业装入内存运行。
(2)当该算法用于进程调度时,将把处理机分配给就绪进程队列中优先级最高的进程。
优先级调度算法细分成如下两种方式:
非抢占式优先级算法
在这种调度方式下,系统一旦把处理机分配给就绪队列中优先级最高的进程后,该进程就能一直执行下去,直至完成;或因等待某事件的发生使该进程不得不放弃处理机时,系统才能将处理机分配给另一个优先级高的就绪进程。
抢占式优先级调度算法
在这种调度方式下,进程调度程序把处理机分配给当时优先级最高的就绪进程,使之执行。一旦出现了另一个优先级更高的就绪进程时,进程调度程序就停止正在执行的进程,将处理机分配给新出现的优先级最高的就绪进程。
进程的优先级可采用静态优先级和动态优先级两种,优先级可由用户自定或由系统确定。
(1)含义
静态优先级是在创建进程时确定进程的优先级,并且规定它在进程的整个运行期间保持不变。
(2)确定优先级的依据(确定优先级的依据通常有下面几个方面)
①进程的类型。通常系统进程优先级高于一般用户进程的优先级;交互型的用户进程的优先级高于批处理作业所对应的进程的优先级。
②进程对资源的需求。例如,进程的估计执行时间及内存需求量少的进程,应赋于较高的优先级,这有利缩小作业的平均周转时间。
③根据用户的要求。用户可以根据自己作业的紧迫程度来指定一个合适的优先级。
(3)优缺点
静态优先级法的优点是
①简单易行 ②系统开销小。
缺点是
①不太灵活,很可能出现低优先级的作业(进程),长期得不到调度而等待的情况。
②静态优先级法仅适用于实时要求不太高的系统。
(1)含义
动态优先级是在创建进程时赋予该进程一个初始优先级,然后其优先级随着进程的执行情况的变化而改变,以便获得更好的调度性能。
(2)优缺点
动态优先级优点是使相应的优先级调度算法比较灵活、科学,可防止有些进程一直得不到调度,也可防止有些进程长期垄断处理机。动态优先级缺点是需要花费相当多的执行程序时间,因而花费的系统开销比较大。
(此算法是根据进程运行时间以及等待时间来确定优先级)
#include "pch.h"
#include
using namespace std;
int main()
{
cout << "请输入进程个数:" << endl;
int processNumber;
cin >> processNumber;
double **array = new double*[processNumber];
for (int i = 0;i < processNumber;i++)//申请空间
{
array[i] = new double[5];
}
for (int i = 0;i < processNumber;i++)//初始化
{
for (int j = 1;j < 5;j++)
array[i][j] = 0;
//array[i][0] = 0;
}
double startTime = 0.0, endTime = 0.0;
cout << "请输入每个进程到达时间和执行时间:" << endl;
for (int i = 0;i < processNumber;i++) {
cin >> startTime >> endTime;
array[i][1] = startTime;
array[i][2] = endTime;
}
double currentTime = array[0][1];
array[0][3] = currentTime + array[0][2];
currentTime += array[0][2];
array[0][4] = currentTime - array[0][1];
array[0][0] = 1;
double temp = 0;
for (int i = 1;i < processNumber;i++)
{
for (int j = i + 1;j < processNumber;j++)
{
if (array[i][2] > array[j][2])
{
temp = array[i][2];
array[i][2] = array[j][2];
array[j][2] = temp;
temp = array[i][1];
array[i][1] = array[j][1];
array[j][1] = temp;
}
}
}
int count = 1;
while (count < processNumber) {
for (int i = 1;i < processNumber;i++)
{
if (array[i][1] < currentTime&&array[i][0] != 1)
{
currentTime += array[i][2];
array[i][3] = currentTime;//填入进程完成时间
array[i][4] = currentTime - array[i][1];//周转时间
count++;
array[i][0] = 1;
}
}
}
for (int i = 0;i < processNumber;i++)
{
array[i][0] = i + 1;
}
cout << "进程号\t" << "开始时间\t" <<"运行时间\t"<<"周转时间\t"<< endl;
for (int i = 0;i < processNumber;i++)
{
for (int j = 0;j < 5;j++)
cout << array[i][j] << " \t";
cout << endl;
}
}
欢迎各位指出不足,以便以后更加完善,