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

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

当进程调度中才有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文件内容如下:

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

 

测试结果如下:

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

 

 

 

1. 实验目的 调度的实质是操作系统按照某种预定的策略来分配资源。进程调度的目的是分配CPU资源。由于进程调度程序执行的频率很高,因此调度算法的好坏直接影响到操作系统的性能。本实验的目的是编程模拟实现几种常用的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。 2. 实验原理 [1]. 进程调度算法描述 进程调度算法包括先来先服务调度算法、最作业时间优先(抢占式和非抢占式)、最高响应比调度算法4种。(每个人必须做FCFS,然后在后面的三种中任选一种,即每个人必须做2种调度算法的模拟。) [2]. 衡量算法性能的参数 计算进程的平均周转时间和平均带权周转时间。 3. 实验内容 (1)编程实现本实验的程序,要求: [1]. 建立进程的进程控制块,进程控制块至少包括: a) 进程名称; b) 进程需要执行时间; c) 进入就绪队列时间; d) 进程执行开始时间 e) 进程执行结束时间 [2]. 编程实现调度算法。 [3]. 进程及相关信息的输入。这些信息可以直接从键盘上输入,也可以从文件读取。 [4]. 时间片与时间流逝的模拟。本实验需要对算法的执行计时,程序应该提供计算时间的方法。一种最简单的方法是使用键盘,比如每敲一次空格代表一个时间片的流逝。另一种方法是使用系统时钟。 [5]. 一组进程序列执行完毕,打印出结果信息。程序需要计算出每个进程的开始执行时间、结束时间、周转时间和带权周转时间,并为整个进程序列计算平均周转时间和平均带权周转时间。程序将计算结果按一定的格式显示在计算机屏幕上或输出到文件中。打印出进程调度顺序图。 [6]. 实现数据在磁盘文件上的存取功能。 (2)对下列就绪进程序列分别使用上面的几种算法进行调度,计算每种算法下的平均周转时间和平均带权周转时间。 进程号 到达时间 要求执行时间 0 0 1 1 1 35 2 2 10 3 3 5 4 6 9 5 7 21 6 9 35 7 11 23 8 12 42 9 13 1 10 14 7 11 20 5 12 23 3 13 24 22 14 25 31
以下是先来先服务(FCFS)和作业优先(SJF)调度算法的代码示例: 先来先服务(FCFS)调度算法: ```python # FCFS调度算法 def fcfs(processes): n = len(processes) # 按照到达时间进行升序排序 processes = sorted(processes, key=lambda x: x[0]) # 计算等待时间和周转时间 waiting_time, turnaround_time = [0] * n, [0] * n for i in range(1, n): waiting_time[i] = waiting_time[i - 1] + processes[i - 1][1] for i in range(n): turnaround_time[i] = waiting_time[i] + processes[i][1] # 计算平均等待时间和平均周转时间 avg_waiting_time = sum(waiting_time) / n avg_turnaround_time = sum(turnaround_time) / n # 返回结果 return avg_waiting_time, avg_turnaround_time ``` 作业优先(SJF)调度算法: ```python # SJF调度算法 def sjf(processes): n = len(processes) # 按照到达时间进行升序排序 processes = sorted(processes, key=lambda x: x[0]) # 初始化等待时间和周转时间 waiting_time, turnaround_time = [0] * n, [0] * n # 记录已经运行的时间 run_time = 0 # 记录已经完成的进程数 completed = 0 # 循环运行进程 while completed < n: # 找到所有已经到达的进程 arrived_processes = [process for process in processes if process[0] <= run_time and process[3] == 0] if not arrived_processes: # 如果当前没有进程到达,则时间加1 run_time += 1 continue # 找到运行时间最的进程 shortest_process = min(arrived_processes, key=lambda x: x[1]) # 更新等待时间和周转时间 index = processes.index(shortest_process) waiting_time[index] = run_time - shortest_process[0] turnaround_time[index] = waiting_time[index] + shortest_process[1] # 更新已经运行的时间和完成的进程数 run_time += shortest_process[1] completed += 1 # 标记已经完成的进程 processes[index][3] = 1 # 计算平均等待时间和平均周转时间 avg_waiting_time = sum(waiting_time) / n avg_turnaround_time = sum(turnaround_time) / n # 返回结果 return avg_waiting_time, avg_turnaround_time ``` 以上两个算法都是使用Python语言编写的。其中,`processes`是一个列表,表示进程的信息。每个进程由四个元素组成,依次为到达时间、运行时间、优先级(如果是SJF算法优先级为运行时间)和完成标志(0表示未完成,1表示已完成)。这两个算法的返回值都是平均等待时间和平均周转时间。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值