操作系统实验-6,作业调度算法模拟
实验6,作业调度算法模拟
1)先来先服务(First-Come First-Served,FCFS)调度算法
先来先服务调度算法遵循按照进入后备队列的顺序进行调度的原则。该算法是一种非抢占式的算法,是到目前为止最简单的调度算法,其编码实现非常容易。该算法仅考虑了作业到达的先后顺序,而没有考虑作业的执行时间长短、作业的运行特性和作业对资源的要求。
2)短作业优先(Shortest-Job-First,SJF)调度算法
短作业优先调度算法根据作业控制块中指出的执行时间,选取执行时间最短的作业优先调度。本实验中规定,该算法是非抢占式的,即不允许立即抢占正在执行中的长进程,而是等当前作业执行完毕再进行调度。
3)响应比高者优先(HRRF)调度算法
FCFS调度算法只片面地考虑了作业的进入时间,短作业优先调度算法考虑了作业的运行时间而忽略了作业的等待时间。响应比高者优先调度算法为这两种算法的折中。响应比为作业的响应时间与作业需要执行的时间之比。作业的响应时间为作业进入系统后的等待时间与作业要求处理器处理的时间之和。
4)优先权高者优先(Highest-Priority-First,HPF)调度算法
优先权高者优先调度算法与响应比高者优先调度算法十分相似,根据作业的优先权进行作业调度,每次总是选取优先权高的作业优先调度。作业的优先权通常用一个整数表示,也叫优先数。优先数的大小与优先权的关系由系统或者用户规定。优先权高者优先调度算法综合考虑了作业执行时间和等待时间的长短、作业的缓急度,作业对外部设备的使用情况等因素,根据系统设计目标和运行环境而给定各个作业的优先权,决定作业调度的先后顺序。
本实验所选用的调度算法均默认为非抢占式调度。
实验所用的测试数据如下表所示。
num reachtime needtime privilege
1 800 50 0
2 815 30 1
3 830 25 2
4 835 20 2
5 845 15 2
6 700 10 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<stdbool.h>
//最大作业数量
#define 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 current_time)
{
int minjob=1000000;
int minloc= -1;
for (int i = 0; i < quantity; i++)
{
//current_time之前有最短作业,取
if(jobs[i].reach_time <= current_time && jobs[i].visited==0)
{
if(jobs[i].need_time < minjob)
{
minjob=jobs[i].need_time;
minloc=i;
}
}
}
int min_reachtime = 100000;
//current_time之前没有作业时
//取current_time之后最先开始的(如果多个项目同时最先开始,取最短的)
if (minloc == -1)
{
for(int i=0;i<quantity;i++)
{
if(jobs[i].visited==0)
{
if(jobs[i].reach_time < min_reachtime)
{
min_reachtime=jobs[i].reach_time;
minloc = i;
minjob = jobs[i].need_time;
}
else if(jobs[i].reach_time==min_reachtime)
{
if(jobs[i].need_time < minjob)
{
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));
}
//短作业优先作业调度
//在current_time之前找最短,都在current_time之后找最近
void SFJschdulejob()
{
int loc=0;
int current_time=0;
int total_waitime=0;
int total_roundtime=0;
int rearlyloc = findrearlyjob(jobs, quantity);//最早到达的作业序号
loc = findminjob(jobs, jobs[rearlyloc].reach_time);
//获取执行时间最短的作业
//输出作业流
printf("\n\nSJF算法作业流\n");
printf("------------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");
current_time=jobs[loc].reach_time;
//每次循环找出最先到达的作业并打印相关信息
for(int 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=findminjob(jobs,current_time);
}
printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);
printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
//高响应比调度算法
int max_excellent(job jobs[], int current_time)
{
int maxjob= -1;
int maxloc= -1;
for (int i = 0; i < quantity; i++)
{
//current_time之前有最高响应比的作业,取
if(jobs[i].reach_time <= current_time && jobs[i].visited==0)
{
if(jobs[i].excellent > maxjob)
{
maxjob=jobs[i].excellent;
maxloc=i;
}
}
}
int min_reachtime = 1000000;
//若current_time之前没有作业,
//取current_time之后最先开始的(如果多个项目同时最先开始,取权值最高的)
if (maxloc == -1)
{
for(int i=0;i<quantity;i++)
{
if(jobs[i].visited==0)
{
if(jobs[i].reach_time < min_reachtime)
{
min_reachtime=jobs[i].reach_time;
maxloc = i;
maxjob = jobs[i].need_time;
}
else if(jobs[i].reach_time==min_reachtime)
{
if(jobs[i].excellent > maxjob)
{
maxjob=jobs[i].excellent;
maxloc=i;
}
}
}
}
}
return maxloc;
}
void HRRFschdulejob()
{
int i;
int current_time=0;
int loc;
int total_waitime=0;
int total_roundtime=0;
float new_excellent=0;
//获取最高响应比的作业
int rearlyloc = findrearlyjob(jobs,quantity);
loc = max_excellent(jobs, jobs[rearlyloc].reach_time);
//输出作业流
printf("\n\nHRRF算法作业流\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;
//获取剩余作业中最近到达作业
for(int j = 0; j < quantity; j++)
{
if(current_time > jobs[j].reach_time && jobs[j].visited == 0)
{
jobs[j].wait_time = current_time - jobs[j].reach_time;
new_excellent =( (float)jobs[j].wait_time + (float)jobs[j].need_time ) / (float)jobs[j].need_time ;
jobs[j].excellent = new_excellent;
}
}
loc = max_excellent(jobs, current_time);
}
printf("总等待时间:%-8d 总周转时间:%-8d\n",total_waitime,total_roundtime);
printf("平均等待时间: %4.2f 平均周转时间: %4.2f\n",(float)total_waitime/(quantity),(float)total_roundtime/(quantity));
}
int max_privilege(job jobs[], int current_time)
{
int maxjob= -1;
int minloc= -1;
for (int i = 0; i < quantity; i++)
{
//current_time之前有最高权值,取
if(jobs[i].reach_time <= current_time && jobs[i].visited==0)
{
if(jobs[i].privilege > maxjob)
{
maxjob=jobs[i].privilege;
minloc=i;
}
}
}
int min_reachtime = 100000;
//current_time之前没有作业,
//取current_time之后最先开始的(如果多个项目同时最先开始,取权值最高的)
if (minloc == -1)
{
for(int i=0;i<quantity;i++)
{
if(jobs[i].visited==0)
{
if(jobs[i].reach_time < min_reachtime)
{
min_reachtime=jobs[i].reach_time;
minloc = i;
maxjob = jobs[i].need_time;
}
else if(jobs[i].reach_time==min_reachtime)
{
if(jobs[i].privilege > maxjob)
{
maxjob=jobs[i].privilege;
minloc=i;
}
}
}
}
}
return minloc;
}
//优先权高者优先调度算法
void HPF()
{
int loc=0;
int current_time=0;
int total_waitime=0;
int total_roundtime=0;
int rearlyloc = findrearlyjob(jobs, quantity);
loc = max_privilege(jobs, jobs[rearlyloc].reach_time);
//获取优先权最高的作业
//输出作业流
printf("\n\nHPF算法作业流\n");
printf("------------------------------------------------------------------------\n");
printf("\tjobID\treachtime\tstarttime\twaittime\troundtime\n");
current_time=jobs[loc].reach_time;
//每次循环找出最先到达的作业并打印相关信息
for(int 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=max_privilege(jobs,current_time);
}
printf("总等待时间:%-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();
HRRFschdulejob();
reset_jinfo();
HPF();
reset_jinfo();
FCFS();
reset_jinfo();
SFJschdulejob();
system("pause");
return 0;
}
执行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2022-04-01 安卓版本与adb的问题