先来先服务和短作业优先调度算法-C语言实现

Posted 三角形ABC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了先来先服务和短作业优先调度算法-C语言实现相关的知识,希望对你有一定的参考价值。

算法介绍

  1. 先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。

  2. 短作业优先(SJF)算法是以进入系统的作业所要求的CPU时间为标准,是指对短作业或者短进程优先调度的算法,将每个进程与其估计运行时间进行关联选取估计计算时间最短的作业投入运行。

内容概括

设计程序模拟进程的先来先服务FCFS和短作业优先SJF调度过程。假设有n个进程分别在T1, … ,Tn时刻到达系统,它们需要的服务时间分别为S1, … ,Sn。分别采用先来先服务FCFS和短作业优先SJF进程调度算法进行调度,计算每个进程的完成时间,周转时间和带权周转时间,并且统计n个进程的平均周转时间和平均带权周转时间。

步骤及代码实现

  1. 定义进程(作业)结构体
#include<stdio.h>
#include<string.h>

struct job
{
    char name[10];      //作业的名字
    int starttime;      //作业到达系统时间
    int needtime;       //作业服务时间
    int runtime;        //作业周转时间
    int endtime;        //作业结束时间
    double dqzz_time;    //带权周转时间
 
};
  1. 定义调用调度函数和结果输出函数。
void fcfs(struct job jobs[50],int n);
void sjf(struct job jobs[50],int n);
void print(struct job jobs[50],int n);
  1. 通过main选择调度算法,并实现所需数据的输入,main函数中调用调度函数和结果输出函数。
void main()
{
    struct job jobs[50];
    int n,i; //n个作业
	int flag;
	printf("请选择调度算法,1:先来先服务 2:短作业优先:");
	scanf("%d",&flag);
    printf("请输入作业个数:");
    scanf("%d",&n);
    printf("请输入各作业的信息(格式:作业名 到达时间 服务时间):\\n");
    for(i=0;i<n;i++)
    {
        scanf("%s",jobs[i].name); //作业名
        scanf("%d",&jobs[i].starttime);//到达时间
        scanf("%d",&jobs[i].needtime);//运行(服务时间)时间
    }
    printf("\\n");

	if(flag==1)
	{
		fcfs(jobs,n);
		printf("先来先服务(FCFS)算法运行结果:\\n");
		print(jobs,n);
	}

	else
	{
		sjf(jobs,n);
		printf("最短作业优先算法(SJF)运行结果:\\n");
		print(jobs,n);
	}
}
  1. 通过先来先服务算法实现定义的fcfs函数,先按照达到时间对作业进行排序,再计算每个作业的结束时间、周转时间及带权周转时间。
void fcfs(struct job jobs[50],int n)
{
   int i=0,j=0;
   char t_name[10];
   int t_time;            
   for(i=0;i<n;i++) //按作业到达系统时间进行排序,最早到达的排在最前面 
	  {
		  for(j=i;j<n;j++) //按作业到达系统时间进行排序,最早到达的排在最前面 
		  {
			  if(jobs[j].starttime<jobs[i].starttime)
			  {   //把到达时间早的赋值到t_time
				  t_time=jobs[j].starttime;
				  jobs[j].starttime=jobs[i].starttime;
				  jobs[i].starttime=t_time;

				  //把到达时间早的赋值到t_time
				  t_time=jobs[j].needtime;
				  jobs[j].needtime=jobs[i].needtime;
				  jobs[i].needtime=t_time;

				  strcpy(t_name,jobs[j].name);
				  strcpy(jobs[j].name,jobs[i].name);
				  strcpy(jobs[i].name,t_name);//在t_name数组中排序
			  }
		  } 

	  }  
   for(i=0;i<n;i++)
   {
	    if(i==0) 
	    {      //第一个进程
	       jobs[i].runtime=jobs[i].needtime;          //周转时间=服务时间
	       jobs[i].endtime=jobs[i].starttime+jobs[i].needtime;     //结束时间=到达时间+服务时间    
	    }
	    else if(jobs[i].starttime>jobs[i-1].endtime)
	    {  //第i个进程到达系统时,第i-1个进程已运行完毕
	       jobs[i].runtime=jobs[i].needtime;  
	       jobs[i].endtime=jobs[i].starttime+jobs[i].needtime;  
	    }
	    else
	    {                              //第i个进程到达系统时,第i-1个进程未运行完毕
	       jobs[i].runtime=jobs[i].needtime+jobs[i-1].endtime-jobs[i].starttime; 
		                                        //周转时间=服务时间+前一个的结束时间-到达时间
	       jobs[i].endtime=jobs[i].starttime+jobs[i].runtime;  //结束时间=到达时间+周转时间
	    }
	    jobs[i].dqzz_time=jobs[i].runtime*1.0/jobs[i].needtime;//带权周转时间=周转时间/服务时间
	}
}
  1. 通过短作业优先算法实现定义的sjf函数,先按照达到时间对作业进行排序,确定第一个作业,再根据其他作业所需要的服务时间确定下一个作业,然后计算每个作业的结束时间、周转时间及带权周转时间。
void sjf(struct job jobs[50],int n)
{
   int i=0,j=0;
   char t_name[10];
   int t_time;            
   for(i=0;i<n;i++) //按作业到达系统时间进行排序,最早到达的排在最前面 
	  {
		  for(j=i;j<n;j++) //按作业到达系统时间进行排序,最早到达的排在最前面 
		  {
			  if(jobs[j].starttime<jobs[i].starttime)
			  {   //把到达时间早的赋值到t_time
				  t_time=jobs[j].starttime;
				  jobs[j].starttime=jobs[i].starttime;
				  jobs[i].starttime=t_time;

				  //把到达时间早的赋值到t_time
				  t_time=jobs[j].needtime;
				  jobs[j].needtime=jobs[i].needtime;
				  jobs[i].needtime=t_time;

				  strcpy(t_name,jobs[j].name);
				  strcpy(jobs[j].name,jobs[i].name);
				  strcpy(jobs[i].name,t_name);//在t_name数组中排序
			  }
		  } 

	  }                      

   jobs[0].endtime=jobs[0].starttime+jobs[0].needtime;//结束时间=到达时间+服务时间
   jobs[0].runtime=jobs[0].needtime;//周转时间=服务时间
   jobs[0].dqzz_time=jobs[0].runtime*1.0/jobs[0].needtime;//带权周转时间=周转时间/服务时间


    for(i=1;i<n;i++)
    {
		for(j=i;j<n;j++)
		{			
			
			if(jobs[i-1].endtime>jobs[j].starttime&&jobs[j].needtime<jobs[i].needtime)
			{ 
				  t_time=jobs[i].starttime;
				  jobs[i].starttime=jobs[j].starttime;
				  jobs[j].starttime=t_time;
                  
				  t_time=jobs[i].needtime;
				  jobs[i].needtime=jobs[j].needtime;
				  jobs[j].needtime=t_time;

				  strcpy(t_name,jobs[i].name);   //将第二个参数的值复制给第一个参数,返回第一个参数
				  strcpy(jobs[i].name,jobs[j].name);
				  strcpy(jobs[j].name,t_name);
			}                 //按最短运行时间排序
		}
		  if(jobs[i].starttime>jobs[i-1].endtime)
		  {                                      //第i个进程到达系统时,第i-1个进程已运行完毕
			jobs[i].endtime=jobs[i].starttime+jobs[i].needtime; 
			jobs[i].runtime=jobs[i].needtime;
		  }
		  else
		  {
			 jobs[i].endtime=jobs[i-1].endtime+jobs[i].needtime;
			 jobs[i].runtime=jobs[i].endtime-jobs[i].starttime; 
		  }
		  jobs[i].dqzz_time=jobs[i].runtime*1.0/jobs[i].needtime;
    }
}
  1. 输出函数实现
void print(struct job jobs[50],int n)
{
    int i;
    double avertime;
    double dqzz_avertime;
    int sum_runtime=0;
    double  sum_time=0.00;
    printf("作业名  到达时间 运行时间 完成时间 周转时间 带权周转时间\\n");
    for(i=0;i<n;i++)
    {
    printf("%s       %2d        %2d        %2d        %2d        %.2f\\n",jobs[i].name,jobs[i].starttime,jobs[i].needtime,jobs[i].endtime,jobs[i].runtime,jobs[i].dqzz_time);
    
    sum_runtime=sum_runtime+jobs[i].runtime;
    sum_time=sum_time+jobs[i].dqzz_time;
    }
    avertime=sum_runtime*1.0/n;
    dqzz_avertime=sum_time*1.000/n;
    printf("平均周转时间:%.2f \\n",avertime);
    printf("平均带权周转时间:%.3f \\n",dqzz_avertime);
    printf("\\n");
}

样例展示

在这里插入图片描述
在这里插入图片描述
参考:https://blog.csdn.net/Hiroomi/article/details/107819906

以上是关于先来先服务和短作业优先调度算法-C语言实现的主要内容,如果未能解决你的问题,请参考以下文章

(转)进程调度算法

进程调度算法

几种进程调度算法总结

Linux 进程调度算法

操作系统有关计算题

使用fcfs,sjf和rr调度算法,并判断哪个算法的平均等待时