先来先服务和短作业优先调度算法

先来先服务调度算法:系统按照作业到达的先后次序来进行调度,或者说它优先考虑在系统中等待时间最长的作业,而不管该作业所需执行时间的长短,从后备作业队列中选择几个最先进入该队列的作业,将它们调入内存,为它们分配资源和创建进程。然后把它放入就绪队列。

当进程调度中才有FCFS算法时,每次调度是从就绪的进程队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后,进程调度程序才将处理机分配给其他进程。

短作业优先调度算法:SJF算法是以作业的长短来计算优先级,作业越短,其优先级越高。作业的长短是以作业所要求的运行时间来衡量的。SJF算法可以分别用于作业调度和进程调度。在把短作业优先调度算法用于作业调度时,它将从外存的作业后备队列中选择若干个估计运行时间最短的作业,优先将它们调入内存运行。

#include<stdio.h>
#include<string.h> 
#include <stdlib.h>
#define N 10				//允许最大进程个数
#define M 100				//进程名长度 
int n;						//进程个数 
char name[N][M]; 			//进程名 
int Arival[N]={0};			//到达时间 
int Go[N]={0};				//运行时间 
int Start[N]={0};			//开始时间 
int End[N]={0};				//结束时间 
int Timer[N]={0};			//周转时间 
float DTimer[N]={0};		//带权周转时间 
int Check[N]={0};			//判断作业是否完成,完成值为1
/*输入函数*/
void input(){
	//为测试方便,采用输入重定义处理
	//每次读取当前文件夹下in.txt文件
	// 若文件不存在,则手动输入 
	int i;
	FILE *fin;  
 	if((fin=fopen("in.txt","rb"))==NULL){
		printf("进程的个数:");
		scanf("%d",&n);
		for(i=0;i<n;i++){
			printf("进程名:");
			scanf("%s",&name[i]);
			printf("第%d个进程的到达时间:",i+1);
			scanf("%d",Arival+i);
			printf("第%d个进程的运行时间:",i+1);
			scanf("%d",Go+i);
		}
	}
	else{
		for(i=0;!feof(fin);i++){
			fscanf(fin,"%s",&name[i]);
			fscanf(fin,"%d",Arival+i);
			fscanf(fin,"%d",Go+i);
		}  
		n=i; 
	} 
}
 /**选出先到达的作业 
 *a[] 到达时间 
 *n 进程个数 
 **/
int Select0(int a[],int n){
	int i=0;
	for(int k=0;k<n;k++){
		if(Check[k]==0){
			i=k;
			break;
		}
	}
	for(int j=0;j<n;j++){
		if(a[i]>a[j]&&Check[j]==0){
			i=j;
		}
	}
	Check[i]=1;
	return i;
}
/*先来先服务调度算法*/
void fcfs(){
	int k=0;			//每次选出即将服务的进程 
	int l=0;			//本次服务的进程 
	int Atimer=0;		//周转时间之和
	float timer=0;		//带权周转时间之和 
	//每次开始之前Check数组要全部置0
	memset(Check,0,sizeof(Check));
	k=Select0(Arival,n);
	Start[k]=Arival[k];
	End[k]=Start[k]+Go[k];
	Timer[k]=End[k]-Arival[k];
	DTimer[k]=(float)Timer[k]/Go[k];
	printf("作业  提交时间  运行时间  开始时间  结束时间  周转时间  带权周转时间\n");
	for(int m=0;m<n;m++){
		l=k;
		k=Select0(Arival,n);
		Start[k]=End[l];
		End[k]=Start[k]+Go[k];
		Timer[k]=End[k]-Arival[k];
		DTimer[k]=(float)Timer[k]/Go[k];
		Atimer=Timer[l]+Atimer;
		timer=timer+DTimer[l];
		printf(" %s     %2d        %2d         %2d        %2d        %2d         %.2f\n",name[l],Arival[l],Go[l],Start[l],End[l],Timer[l],DTimer[l]);
	}
	printf("平均周转时间:%.2f\n",(float)Atimer/n);
	printf("平均带权周转时间:%.2f\n",(float)timer/n);
}
/**选出短作业 
 *a[] 运行时间 
 *n 进程个数 
 *local 当前时间 
 **/
int Select1(int a[],int n,int local){
	int i=0;
	for(int k=0;k<n;k++){
		if(Check[k]==0){
			i=k;
			break;
		}
	}
	for(int j=0;j<n;j++){
		if(a[i]>a[j]&&Check[j]==0&&Arival[j]<=local){
			i=j;
		}
	}
	Check[i]=1;
	return i;
}
/*短作业优先调度算法*/
void sjf(){
	int k=0;			//每次选出即将服务的进程 
	int l=0;			//本次服务的进程 
	int Atimer=0;		//周转时间之和
	float timer=0;		//带权周转时间之和 
	int localtime=0;	//当前时间 
	//每次开始之前Check数组要全部置0
	memset(Check,0,sizeof(Check));
	Start[k]=Arival[k];
	End[k]=Start[k]+Go[k];
	Timer[k]=End[k]-Arival[k];
	DTimer[k]=(float)Timer[k]/Go[k];
	localtime=End[k];
	Check[k]=1;
	printf("作业  提交时间  运行时间  开始时间  结束时间  周转时间  带权周转时间\n");
	for(int m=0;m<n;m++){
		l=k;
		k=Select1(Go,n,localtime);
		Start[k]=End[l];
		End[k]=Start[k]+Go[k];
		Timer[k]=End[k]-Arival[k];
		DTimer[k]=(float)Timer[k]/Go[k];
		localtime=End[k];
		Atimer=Timer[l]+Atimer;
		timer=timer+DTimer[l];
		printf(" %s     %2d        %2d         %2d        %2d        %2d         %.2f\n",name[l],Arival[l],Go[l],Start[l],End[l],Timer[l],DTimer[l]);
	}
	printf("平均周转时间:%.2f\n",(float)Atimer/n);
	printf("平均带权周转时间:%.2f\n",(float)timer/n);
} 
void menu(){
	int choice;
	while(1){
		printf("*******请选择调度算法*******\n\t1、先来先服务\n\t2、短作业优先\n\t0、退出\n请输入:");
		scanf("%d",&choice);
		if(choice==0){
			break;
		}
		else if(choice==1){
			fcfs();
		}
		else if(choice==2){
			sjf(); 
		}
		else{
			printf("输入有误!\n");		
		}
		
	}	
}
int main(){
	input();
	menu();
	return 0;
}

为测试方便,采用输入重定向的方法,每次读取当前程序文件目录下的in.txt文件,若文件不存在则手动输入。

 

in.txt文件内容如下:

内容格式依次为:作业名、到达时间、服务时间

 

测试结果如下:

若文件不存在,则手动输入,结果如下:

 

 

 

  • 53
    点赞
  • 307
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值