短作业优先调度算法C语言实现

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

完成时间 = 开始时间 + 需要运行时间
周转时间 = 完成时间 - 到达时间
带权周转时间 = 周转时间 / 需要运行时间

实验内容:

按作业提交的/到达的(到达后备队列的时间)先后次序从外存后备队列中选择几个最先进入该队列的作业为他们分配资源、创建进程,然后再放入就绪队列。

每个作业由一个作业控制块JCB表示,JCB可以包含如下信息∶作业名、提交时间、所需的运行时间、作业状态等等。

作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。各个等待的作业按照提交时刻的先后次序排队。

每个作业完成后要输出该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后计算并输出这组作业的平均周转时间、平均带权周转时间。

#include <iostream>
#include <string.h>
#include <iomanip>

struct job
{
    char name[10];      //作业的名字
    int starttime;      //作业到达系统时间
    int needtime;       //作业服务时间
    int runtime;        //作业周转时间
    int endtime;        //作业结束时间
    int flag=0;           //作业完成标志   
	char state='W'; 		//作业状态,一开始都默认为就绪 
	double dqzz_time;    //带权周转时间
};

void sjf(struct job jobs[50],int n){
 	int i=0,j=0,k,temp,count=0,min_needtime,min_starttime,t_time,flag1;
    char t_name[10];
    int nowtime=0;
    for(i=0;i<n;i++) //按作业到达系统时间进行排序,最早到达的排在最前面 
	{
		min_needtime=jobs[i].needtime;
		temp=i;
		for(j=i;j<n;j++) //按作业到达系统时间进行排序,最早到达的排在最前面 
		{
			if(jobs[j].needtime<min_needtime)
			{  
				temp=j;
				min_needtime=jobs[j].needtime;
			}
		}
		if(temp!=i)
		{
			jobs[40]=jobs[temp];
			for(k=temp-1;k>=i;k--)
			{
				jobs[k+1]=jobs[k];
			}
			jobs[i]=jobs[40];		
		}    
	}	    
	while(count<n){
		temp=1000; 
		flag1=0;
		min_needtime=1000;
		min_starttime=1000;
		for(i=0;i<n;i++){
			if(jobs[i].flag==0){
				if(jobs[i].starttime<=nowtime)
				{
					flag1=1;
					if(jobs[i].needtime<min_needtime){
						min_needtime=jobs[i].needtime;
						temp=i;
					}
				}
			}
		}
		if(flag1==0)
		{
			for(i=0;i<n;i++){
				if(jobs[i].flag==0){
					if(jobs[i].starttime<min_starttime){
						min_starttime=jobs[i].starttime;
						temp=i;
					}
				}
			}
			nowtime=jobs[temp].starttime+jobs[temp].needtime;
			jobs[temp].endtime=nowtime;
 			jobs[temp].flag=1;
 			jobs[temp].runtime=jobs[temp].endtime-jobs[temp].starttime;
 			jobs[temp].dqzz_time=float(jobs[temp].runtime)/jobs[temp].needtime;
 			count++;
		}
		else{
			nowtime+=jobs[temp].needtime;
			jobs[temp].endtime=nowtime;
 			jobs[temp].flag=1;
 			jobs[temp].runtime=jobs[temp].endtime-jobs[temp].starttime;
 			jobs[temp].dqzz_time=float(jobs[temp].runtime)/jobs[temp].needtime;
 			count++;
		}
	}
	
}	
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");
}

int main()
{
    struct job jobs[50];
    int n,i; //n个作业
    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");
	sjf(jobs,n);
	printf("先来先服务(FCFS)调度算法运行结果:\n");
	print(jobs,n);
	
}

运行结果

由于忘记改了,大家记得把最后一行的printf里的文字改为短作业优先算法,sjf

11.9更新

对代码做出了一些修改,加了一些注释,并对输出按照endtime进行排序,这样看起来更直观

#include <iostream>
#include <string.h>
#include <iomanip>

struct job
{
    char name[10];      //作业的名字
    int starttime;      //作业到达系统时间
    int needtime;       //作业服务时间
    int runtime;        //作业周转时间
    int endtime;        //作业结束时间
    int flag=0;           //作业完成标志   
	char state='W'; 		//作业状态,一开始都默认为就绪 
	double dqzz_time;    //带权周转时间
};

void sjf(struct job jobs[50],int n){
 	int i=0,j=0,k,temp,count=0,min_needtime,min_starttime,t_time,flag1;
    char t_name[10];
    int nowtime=0;
    for(i=0;i<n;i++) //按作业所需运行时间排序,短的排在最前面 
	{
		min_needtime=jobs[i].needtime;//n轮循环,每次都把job[j]与job[i]的所需运行时间相比较,从而找到位于job[i]后的最短的运行时间 
		temp=i;
		for(j=i;j<n;j++) 
		{
			if(jobs[j].needtime<min_needtime)
			{  
				temp=j;
				min_needtime=jobs[j].needtime;
			}
		}
		if(temp!=i)//存在更短的运行时间 
		{
			jobs[40]=jobs[temp];//中间变量 
			for(k=temp-1;k>=i;k--)//将位于jobs[temp]前的jobs向左平移 
			{
				jobs[k+1]=jobs[k];
			}
			jobs[i]=jobs[40];		
		}    
	}	    
	while(count<n){//作业未全部运行完 
		temp=1000; 
		flag1=0; 
		min_needtime=1000;
		min_starttime=1000;
		for(i=0;i<n;i++){
			if(jobs[i].flag==0){
				if(jobs[i].starttime<=nowtime)//存在未完成且等待的作业 
				{
					flag1=1;
					if(jobs[i].needtime<min_needtime){//找出所需运行时间最短的作业 
						min_needtime=jobs[i].needtime;
						temp=i;
					}
				}
			}
		}
		if(flag1==0)//如果所有未完成的作业都没等待 
		{
			for(i=0;i<n;i++){
				if(jobs[i].flag==0){
					if(jobs[i].starttime<min_starttime){//找出最先到达的作业 
						min_starttime=jobs[i].starttime;
						temp=i;
					}
				}
			}
			nowtime=jobs[temp].starttime+jobs[temp].needtime;//系统时间从作业到达时间开始 
			jobs[temp].state='r';
			jobs[temp].endtime=nowtime;
 			jobs[temp].flag=1;
 			jobs[temp].runtime=jobs[temp].endtime-jobs[temp].starttime;
 			jobs[temp].dqzz_time=float(jobs[temp].runtime)/jobs[temp].needtime;
 			jobs[temp].state='f'; 
 			count++;
		}
		else{//有等待的作业 
			nowtime+=jobs[temp].needtime;//从系统时间开始运行 
			jobs[temp].state='r';
			jobs[temp].endtime=nowtime;
 			jobs[temp].flag=1;
 			jobs[temp].runtime=jobs[temp].endtime-jobs[temp].starttime;
 			jobs[temp].dqzz_time=float(jobs[temp].runtime)/jobs[temp].needtime;
 			jobs[temp].state='f'; 
 			count++;
		}
	}
	
}	
void print(struct job jobs[50],int n)
{
    int i,j;
    double avertime;
    double dqzz_avertime;
    int sum_runtime=0;
    double  sum_time=0.00;
    for(i=0;i<n;i++) //按作业完成时间进行排序,完成早的排在最前面 
	{
		for(j=i;j<n;j++)
		{
			if(jobs[j].endtime<jobs[i].endtime)
			{   
			  	jobs[45]=jobs[j];
				jobs[j]=jobs[i];
				jobs[i]=jobs[45]; 
			}
		} 
    }
    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");
}

int main()
{
    struct job jobs[50];
    int n,i; //n个作业
    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");
	sjf(jobs,n);
	printf("先来先服务(FCFS)调度算法运行结果:\n");
	print(jobs,n);
	
}

上述流程实现

t012345678910111213141516
wBBCDBCBECBECECECECCCCC
rAAAADDBBBEEEECCCC
fAAADADADADBADBADBADBADBEADBEADBE
t161718
w
rCC
fADBEADBEADBEC

其中对于下面这部分代码,我觉得可以改进

		for(i=0;i<n;i++){
			if(jobs[i].flag==0){
				if(jobs[i].starttime<=nowtime)//存在未完成且等待的作业 
				{
					flag1=1;
					if(jobs[i].needtime<min_needtime){//找出所需运行时间最短的作业 
						min_needtime=jobs[i].needtime;
						temp=i;
					}
				}
			}
		}

由于本来就是先按照最短运行时间作业进行排序

 只要找到了符合未完成且等待的作业,就可以break,跳出这个循环,不需要继续和后面的比较,读者可以自己试一下

#include //定义一个结构体 struct sjf{ char name[10]; //进程名 float arrivetime; //到达时间 float servicetime;//服务时间 float starttime; //开始时间 float finishtime;//完成时间 float zztime;//周转时间 float dqzztime;//带权周转 }; //定义一个结构体数组 sjf a[100]; //定义一个输入函数 void input(sjf *p,int N) { int i; printf("intput the process's name & arrivetime & servicetime:\nfor exmple: a 0 100\n"); for(i=0;i<=N-1;i++) { printf("input the %dth process's information:\n",i+1); scanf("%s%f%f",&p[i].name,&p[i].arrivetime,&p[i].servicetime); } } //定义一个输出函数 void Print(sjf *p,float arrivetime,float servicetime,float starttime,float finishtime,float zztime,float dqzztime,int N) { int k; printf("run order:");//执行顺序 printf("%s",p[0].name); for(k=1;k%s",p[k].name); } printf("\nthe process's information:\n"); printf("\nname\tarrive\tservice\tstart\tfinish\tzz\tdqzz\n"); for(k=0;k<=N-1;k++) { printf("%s\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t\n",p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k].finishtime,p[k].zztime,p[k].dqzztime); } } //按到达时间排序 void sort(sjf *p,int N) { for(int i=0;i<=N-1;i++) for(int j=0;j<=i;j++) if(p[i].arrivetime<p[j].arrivetime) { sjf temp; temp=p[i]; p[i]=p[j]; p[j]=temp; } } //运行阶段 void deal(sjf *p, float arrivetime,float servicetime,float starttime,float finishtime,float &zztime,float &dqzztime,int N) { int k; for(k=0;k=p[k].arrivetime) { p[k].starttime=p[k-1].finishtime;} else { p[k].starttime =p[k].arrivetime;} p[k].finishtime=p[k].starttime+p[k].servicetime; } } for(k=0;k<=N-1;k++) { p[k].zztime=p[k].finishtime-p[k].arrivetime;//周转时间=完成时间-到达时间 p[k].dqzztime=p[k].zzti
既然你想了解短作业优先算法的C语言编程实现,那么我们可以先了解一下这种调度算法的基本思想。短作业优先算法又称为SJF算法,它的核心思想是优先调度执行时间短的进程。对于所有正在等待处理器的进程,按照它们的执行时间升序进行排序,然后选择执行时间最短的进程先被调度执行。这种算法相对其他调度算法来说,它能够有效的缩短进程的等待时间,提高系统的响应速度。下面是一个具体实现的C语言代码范例: ```c #include <stdio.h> #include <stdlib.h> #define max 50 struct process { int pid; // 进程ID int burst_time; // 执行时间 int waiting_time; // 等待时间 int turnaround_time; // 周转时间 }; int sjf(struct process p[], int n) { // 短作业优先调度算法 int i, j, shortest; float avwt = 0; // 平均等待时间 float avtat = 0; // 平均周转时间 for (i = 0; i < n; i++) { shortest = i; for (j = i + 1; j < n; j++) { if (p[j].burst_time < p[shortest].burst_time) { shortest = j; } } struct process temp = p[i]; p[i] = p[shortest]; p[shortest] = temp; p[i].waiting_time = 0; p[i].turnaround_time = p[i].burst_time; for (j = 0; j < i; j++) { p[i].waiting_time += p[j].burst_time; } avwt += p[i].waiting_time; avtat += p[i].turnaround_time; } printf("\nProcess\tBurst Time\tWaiting Time\tTurnaround Time"); for (i = 0; i < n; i++) { printf("\n%d\t\t%d\t\t%d\t\t%d", p[i].pid, p[i].burst_time, p[i].waiting_time, p[i].turnaround_time); } printf("\n\nAverage waiting time = %f", avwt / n); printf("\nAverage turnaround time = %f", avtat / n); } int main() { struct process p[max]; int n, i; printf("Enter the number of processes: "); scanf("%d", &n); printf("\nEnter the burst time of each process:\n"); for (i = 0; i < n; i++) { printf("Process %d: ", i + 1); p[i].pid = i + 1; scanf("%d", &p[i].burst_time); } sjf(p, n); return 0; } ``` 上述代码中,我们首先定义了一个包含进程ID、执行时间、等待时间、周转时间等信息的结构体`process`,然后定义了一个`sjf`函数,该函数实现短作业优先调度算法,返回平均等待时间和平均周转时间。在`main`函数中,我们首先输入了进程数和每个进程的执行时间,并调用`sjf`函数进行调度。最后输出每个进程的执行时间、等待时间、周转时间,以及平均等待时间和平均周转时间。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值