基本调度算法
1)先来先服务(First-Come First-Served,FCFS)调度算法
先来先服务调度算法遵循按照进入后备队列的顺序进行调度的原则。该算法是一种非抢占式的算法,是到目前为止最简单的调度算法,其编码实现非常容易。该算法仅考虑了作业到达的先后顺序,而没有考虑作业的执行时间长短、作业的运行特性和作业对资源的要求。
2)短作业优先(Shortest-Job-First,SJF)调度算法
短作业优先调度算法根据作业控制块中指出的执行时间,选取执行时间最短的作业优先调度。本实验中规定,该算法是非抢占式的,即不允许立即抢占正在执行中的长进程,而是等当前作业执行完毕再进行调度。
3)响应比高者优先(HRRF)调度算法
FCFS调度算法只片面地考虑了作业的进入时间,短作业优先调度算法考虑了作业的运行时间而忽略了作业的等待时间。响应比高者优先调度算法为这两种算法的折中。响应比为作业的响应时间与作业需要执行的时间之比。作业的响应时间为作业进入系统后的等待时间与作业要求处理器处理的时间之和。
4)优先权高者优先(Highest-Priority-First,HPF)调度算法
优先权高者优先调度算法与响应比高者优先调度算法十分相似,根据作业的优先权进行作业调度,每次总是选取优先权高的作业优先调度。作业的优先权通常用一个整数表示,也叫优先数。优先数的大小与优先权的关系由系统或者用户规定。优先权高者优先调度算法综合考虑了作业执行时间和等待时间的长短、作业的缓急度,作业对外部设备的使用情况等因素,根据系统设计目标和运行环境而给定各个作业的优先权,决定作业调度的先后顺序。
本实验所选用的调度算法均默认为非抢占式调度。
实验所用的测试数据如下表所示。
本实验所用的测试数据如下表所示
表 实验测试数据
作业Id | 到达时间 | 执行时间 | 优先权 |
1 | 800 | 50 | 0 |
2 | 815 | 30 | 1 |
3 | 830 | 25 | 2 |
4 | 835 | 20 | 2 |
5 | 845 | 15 | 2 |
6 | 700 | 10 | 1 |
7 | 820 | 5 | 0 |
以下是对上述四个算法的模拟
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 最大作业数量
const int MAXJOB = 50;
// 作业的数据结构
typedef struct node
{int number; // 作业号int reach_time; // 作业抵达时间int need_time; // 作业的执行时间int privilege; // 作业优先权float excellent; // 响应比int start_time; // 作业开始时间int wait_time; // 等待时间int visited; // 作业是否被访问过bool isreached; // 作业是否抵达
} job;
job jobs[MAXJOB]; // 作业序列
int quantity; // 作业数量
// 初始化作业序列
void initial_jobs()
{int i;for (i = 0; i < MAXJOB; i++){jobs[i].number = 0;jobs[i].reach_time = 0;jobs[i].privilege = 0;jobs[i].excellent = 0;jobs[i].start_time = 0;jobs[i].wait_time = 0;jobs[i].visited = 0;jobs[i].isreached = false;}quantity = 0;
}
// 重置全部作业信息
void reset_jinfo()
{int i;for (i = 0; i < MAXJOB; i++){jobs[i].start_time = 0;jobs[i].wait_time = 0;jobs[i].visited = 0;}
}
// 查找当前current_time已到达未执行的最短作业,若无返回-1
int findminjob(job jobs[], int count)
{int minjob = -1; //=jobs[0].need_time;int minloc = -1;for (int i = 0; i < count; i++){if (minloc == -1){if (jobs[i].isreached == true && jobs[i].visited == 0){minjob = jobs[i].need_time;minloc = i;}}else if (minjob > jobs[i].need_time && jobs[i].visited == 0 && jobs[i].isreached == true){minjob = jobs[i].need_time;minloc = i;}}return minloc;
}
// 查找最早到达作业,若全部到达返回-1.
int findrearlyjob(job jobs[], int count)
{int rearlyloc = -1;int rearlyjob = -1;for (int i = 0; i < count; i++){if (rearlyloc == -1){if (jobs[i].visited == 0){rearlyloc = i;rearlyjob = jobs[i].reach_time;}}else if (rearlyjob > jobs[i].reach_time && jobs[i].visited == 0){rearlyjob = jobs[i].reach_time;rearlyloc = i;}}return rearlyloc;
}
// 读取作业数据
void readJobdata()
{FILE *fp;char fname[20];int i;// 输入测试文件文件名printf("please input job data file name\n");scanf("%s", fname);if ((fp = fopen(fname, "r")) == NULL){printf("error, open file failed, please check filename:\n");}else{// 依次读取作业信息while (!feof(fp)){if (fscanf(fp, "%d %d %d %d", &jobs[quantity].number, &jobs[quantity].reach_time, &jobs[quantity].need_time, &jobs[quantity].privilege) == 4)quantity++;}// 打印作业信息printf("output the origin job data\n");printf("---------------------------------------------------------------------\n");printf("\tjobID\treachtime\tneedtime\tprivilege\n");for (i = 0; i < quantity; i++){printf("\t%-8d\t%-8d\t%-8d\t%-8d\n", jobs[i].number, jobs[i].reach_time, jobs[i].need_time, jobs[i].privilege);}}
}
// FCFS
void FCFS()
{int i;int current_time = 0;int loc;int total_waitime = 0;int total_roundtime = 0;// 获取最近到达的作业loc = findrearlyjob(jobs, quantity);// 输出作业流printf("\n\nFCFS算法作业流\n");printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");current_time = jobs[loc].reach_time;// 每次循环找出最先到达的作业并打印相关信息for (i = 0; i < quantity; i++){if (jobs[loc].reach_time > current_time){jobs[loc].start_time = jobs[loc].reach_time;current_time = jobs[loc].reach_time;}else{jobs[loc].start_time = current_time;}jobs[loc].wait_time = current_time - jobs[loc].reach_time;printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n", loc + 1, jobs[loc].reach_time, jobs[loc].start_time, jobs[loc].wait_time,jobs[loc].wait_time + jobs[loc].need_time);jobs[loc].visited = 1;current_time += jobs[loc].need_time;total_waitime += jobs[loc].wait_time;total_roundtime = total_roundtime + jobs[loc].wait_time + jobs[loc].need_time;// 获取剩余作业中最近到达作业loc = findrearlyjob(jobs, quantity);}printf("总等待时间:%-8d 总周转时间:%-8d\n", total_waitime, total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n", (float)total_waitime / (quantity), (float)total_roundtime / (quantity));
}
// 短作业优先作业调度void swap_job(int i, int j)
{jobs[quantity] = jobs[i];jobs[i] = jobs[j];jobs[j] = jobs[quantity];
}void sort_job()
{int loc;for (int i = 0; i < quantity - 1; i++){loc = findrearlyjob(jobs, quantity);jobs[loc].visited = 1;swap_job(loc, i);}for (int i = 0; i < quantity - 1; i++)jobs[i].visited = 0;
}//
// 短作业优先作业调度
void SFJschdulejob(job jobs[], int count)
{printf("\n\nSFJ算法作业流\n");printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");int current_time = 0;int loc = 0;int total_waitime = 0;int total_roundtime = 0;int f;sort_job();for (int i = 0; i < quantity; i++){f = 1;loc = findminjob(jobs, quantity);if (i == 0)loc = 0;if (current_time < jobs[loc].reach_time)current_time = jobs[loc].reach_time;jobs[loc].start_time = current_time;jobs[loc].wait_time = current_time - jobs[loc].reach_time;jobs[loc].visited = 1;total_waitime += jobs[loc].wait_time;total_roundtime += jobs[loc].need_time + jobs[loc].wait_time;current_time = jobs[loc].start_time + jobs[loc].need_time;for (int j = i + 1; j < quantity; j++){if (jobs[j].reach_time <= current_time && jobs[j].isreached == false){jobs[j].isreached = true;f = 0;}}if (f){jobs[i + 1].isreached = true;}printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n", jobs[loc].number, jobs[loc].reach_time,jobs[loc].start_time, jobs[loc].wait_time,jobs[loc].wait_time + jobs[loc].need_time);// for (int i = 0; i < quantity; i++)// printf("%d\n", jobs[i].isreached);// printf("%d\n", jobs[loc].number);}// coutprintf("总等待时间:%-8d 总周转时间:%-8d\n", total_waitime, total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n", (float)total_waitime / (quantity), (float)total_roundtime / (quantity));
}
// 高响应比调度算法int findExcjob(job jobs[], int count)
{int minjob = -1; //=jobs[0].need_time;int minloc = -1;for (int i = 0; i < count; i++){// printf("%d\n", jobs[i].number);if (minloc == -1){if (jobs[i].isreached == true && jobs[i].visited == 0){minjob = jobs[i].excellent;minloc = i;// printf("%d %f\n", jobs[i].number, jobs[i].excellent);}}else if (minjob < jobs[i].excellent && jobs[i].visited == 0 && jobs[i].isreached == true){minjob = jobs[i].excellent;minloc = i;// printf("%d %f\n", jobs[i].number, jobs[i].excellent);}// else if (jobs[i].isreached == true && jobs[i].visited == 0)// printf("%d %f\n", jobs[i].number, jobs[i].excellent);}// printf("loc=%d\n", jobs[minloc].number);// printf("\n");return minloc;
}// 高响应比调度算法
void HRRFschdulejob()
{printf("\n\nHRRF算法作业流\n");printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");int current_time = 0;int loc = 0;int total_waitime = 0;int total_roundtime = 0;int f;sort_job();for (int i = 0; i < quantity; i++){f = 1;loc = findExcjob(jobs, quantity);if (i == 0)loc = 0;if (current_time < jobs[loc].reach_time)current_time = jobs[loc].reach_time;jobs[loc].start_time = current_time;jobs[loc].wait_time = current_time - jobs[loc].reach_time;jobs[loc].visited = 1;total_waitime += jobs[loc].wait_time;total_roundtime += jobs[loc].need_time + jobs[loc].wait_time;current_time = jobs[loc].start_time + jobs[loc].need_time;for (int j = i + 1; j < quantity; j++){if (jobs[j].reach_time <= current_time && jobs[j].isreached == false){jobs[j].isreached = true;f = 0;}}if (f){jobs[i + 1].isreached = true;}for (int j = i + 1; j < quantity; j++){if (jobs[j].isreached)jobs[j].excellent = (float)(jobs[loc].start_time + jobs[loc].need_time - jobs[j].reach_time) / (float)jobs[j].need_time;}printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n", jobs[loc].number, jobs[loc].reach_time,jobs[loc].start_time, jobs[loc].wait_time,jobs[loc].wait_time + jobs[loc].need_time);// for (int i = 0; i < quantity; i++)// printf("%d\n", jobs[i].isreached);// printf("%d\n", jobs[loc].number);}// coutprintf("总等待时间:%-8d 总周转时间:%-8d\n", total_waitime, total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n", (float)total_waitime / (quantity), (float)total_roundtime / (quantity));
}
// 优先权高者优先调度算法int findPrijob(job jobs[], int count)
{int MaxP = -1; //=jobs[0].need_time;int MaxLoc = -1;for (int i = 0; i < count; i++){// printf("%d\n", jobs[i].number);if (MaxLoc == -1){if (jobs[i].isreached == true && jobs[i].visited == 0){MaxP = jobs[i].privilege;MaxLoc = i;}}else if (MaxP < jobs[i].privilege && jobs[i].visited == 0 && jobs[i].isreached == true){MaxP = jobs[i].privilege;MaxLoc = i;}}return MaxLoc;
}
// 优先权高者优先调度算法
void HPF(job jobs[])
{printf("\n\nHPF算法作业流\n");printf("------------------------------------------------------------------------\n");printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");int current_time = 0;int loc = 0;int total_waitime = 0;int total_roundtime = 0;int f;sort_job();for (int i = 0; i < quantity; i++){f = 1;loc = findPrijob(jobs, quantity);if (i == 0)loc = 0;if (current_time < jobs[loc].reach_time)current_time = jobs[loc].reach_time;jobs[loc].start_time = current_time;jobs[loc].wait_time = current_time - jobs[loc].reach_time;jobs[loc].visited = 1;total_waitime += jobs[loc].wait_time;total_roundtime += jobs[loc].need_time + jobs[loc].wait_time;current_time = jobs[loc].start_time + jobs[loc].need_time;for (int j = i + 1; j < quantity; j++){if (jobs[j].reach_time <= current_time && jobs[j].isreached == false){jobs[j].isreached = true;f = 0;}}if (f){jobs[i + 1].isreached = true;}printf("\t%-8d\t%-8d\t%-8d\t%-8d\t%-8d\n", jobs[loc].number, jobs[loc].reach_time,jobs[loc].start_time, jobs[loc].wait_time,jobs[loc].wait_time + jobs[loc].need_time);}// coutprintf("总等待时间:%-8d 总周转时间:%-8d\n", total_waitime, total_roundtime);printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n", (float)total_waitime / (quantity), (float)total_roundtime / (quantity));
}
int main()
{initial_jobs();readJobdata();FCFS();reset_jinfo();SFJschdulejob(jobs, quantity);reset_jinfo();HPF(jobs);reset_jinfo();HRRFschdulejob();reset_jinfo();system("pause");return 0;
}