操作系统实验-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;
}


执行结果:
在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值