短作业优先(Shortest Process Next,SPN)的进程调度算法模拟

  • 1.SPN算法思想

短作业优先(Shortest Process Next,SPN)的调度算法,由于在实际情况中,短进程(作业)占有很大比例,为了能使它们能比长进程(作业)优先执行,而产生了短进程(作业)优先调度算法。

算法思想:从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行。

SPN调度算法较之FCFS算法有了明显的改进,但仍然存在不容忽视的缺点:
  (1) 必须预知作业的运行时间。在采用这种算法时,要先知道每个作业的运行时间。即使是程序员也很难准确估计作业的运行时间,如果估计过低,系统就可能按估计的时间终止作业的运行,但此时作业并未完成,故一般都会偏长估计。
  (2) 对长作业非常不利,长作业的周转时间会明显地增长。更严重的是,该算法完全忽视作业的等待时间,可能使作业等待时间过长,出现饥饿现象。

       (3) 在采用FCFS算法时,人-机无法实现交互。

  (4) 该调度算法完全未考虑作业的紧迫程度,故不能保证紧迫性作业能得到及时处理。

  • 2.代码模拟实现
#include<bits/stdc++.h>//万能头文件 
using namespace std;
struct job 
{
	char name[10];//作业的名字
	int starttime;//作业到达时间 
	int needtime;//作业服务时间 
	int runtime;//作业周转时间 
	int endtime;//作业结束时间 
	double dqzz_time;//带权周转时间 
	bool finished;//作业完成标志 
	
}; 
bool campare_start(struct job job1,struct job job2)//自定义排序方式,按到达顺序从大到小排,保证jobs[0]为第一个到达的进程 
{
	return job1.starttime<job2.starttime;

 } 
void print_SPN(struct job jobs[50],int n)
{
	double a_runtime=0;//平均周转时间 
	double a_dqzz_time=0;//平均带权周转时间
	double sum_time1=0;//总周转时间 
	double sum_time2=0; //总带权周转时间 
	
	for(int i=0;i<n;i++)
	{
		cout<<"作业名:"<<jobs[i].name<<" 到达时间:"<<jobs[i].starttime<<" 运行时间:"<<jobs[i].needtime<<" 完成时间:"
		<<jobs[i].endtime<<" 周转时间"<<jobs[i].runtime<<" 带权周转时间:"<<jobs[i].dqzz_time<<endl;
		sum_time1+=jobs[i].runtime;
		sum_time2+=jobs[i].dqzz_time; 
	 } 
	 a_runtime=sum_time1/n;
	 a_dqzz_time=sum_time2/n;
	 cout<<"平均周转时间"<<a_runtime<<endl; 
	 cout<<"平均带权周转时间"<<a_dqzz_time<<endl;
 } 
void SPN(struct job jobs[50],int n)
{
	int  last_finished_index; //记录上一次已经运行的进程的数组下标
	jobs[0].endtime=jobs[0].starttime+jobs[0].needtime;//完成时间 
	jobs[0].runtime=jobs[0].endtime-jobs[0].starttime;//周转时间
	jobs[0].dqzz_time=double(jobs[0].runtime)/jobs[0].needtime;//带权周转时间
	jobs[0].finished=true;
	last_finished_index=0;
	int index;//保存每次最短服务时间进程的索引。
	int min_time;
	int job_endtime;//保存上一进程的结束时间 
	for(int i=1;i<n;i++)
	{	
		min_time=1000;//1.初始化,防止min-time太小,影响查找最短服务时间的进程.
		job_endtime=jobs[last_finished_index].endtime;
		index=-1;//初始化,可用来判断所有进程是否完成 
		for(int j=1;j<n;j++)//找到最短服务时间的进程 
		{
			if(min_time>jobs[j].needtime&&jobs[j].finished==false&&job_endtime>=jobs[j].starttime)
			//上一进程的结束时间,应该在进程A到达时间之后,进程A才能进就绪队列,才能参与排序 
		{
			min_time=jobs[j].needtime;
			index=j; 
		}
		
		 } 
		jobs[index].endtime=jobs[last_finished_index].endtime+jobs[index].needtime;//完成时间 
		jobs[index].runtime=jobs[index].endtime-jobs[index].starttime;//周转时间
		jobs[index].dqzz_time=double(jobs[index].runtime)/jobs[index].needtime;//带权周转时间
		jobs[index].finished=true;
		last_finished_index=index;
		if(last_finished_index==-1)//所有进程已完成,退出 
		{
			break;
		}
	 } 
}
int main()
{
	struct job jobs[50];
	int n;//n个作业
	cout<<"请输入作业个数"<<endl;
	cin>>n;
	cout<<"请输入各作业的信息(作业名 到达时间 服务时间):"<<endl;
	for(int i=0;i<n;i++)
	{	cin>>jobs[i].name;
		cin>>jobs[i].starttime;
		cin>>jobs[i].needtime;

		}
	SPN(jobs,n);//调用SPN算法 
	cout<<"SPN调度算法运行结果:"<<endl;
	print_SPN(jobs,n);	//打印SPN运行结果  
	return 0;
 }
  • 3.运行结果

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值