操作系统:实验三 SJF调度算法模拟

目录

一、实验目的与要求

二、实验环境

三、实验内容

四、实验结果展示

五、实验总结和思考


一、实验目的与要求

  1. 加深对作业/进程调度算法的理解;
  2. 进行程序设计的训练;
  3. 学会使用高级语言编写一个或多个算法的模拟程序。

二、实验环境

Ubuntu、centos、Windows系统

三、实验内容

使用c语言完成非抢占式SJF算法的模拟,短作业优先(非抢占式)算法按照作业或进程到达时间的先后及所需运行时间长短排队,先到的进程先调度,同时到达的进程所需运行时间短的优先调度。

每个进程由一个进程控制块PCB表示,包含以下信息:进程名、进程ID、提交(到达)系统时间、开始时间、运行时间、完成时间、进程状态(就绪、阻塞、执行)等。

1.模拟数据生成

允许用户指定进程的个数(5-25个),默认5个。

允许用户选择输入每个进程的到达时间和所需运行时间。

2.模拟程序的功能

以表格形式打印显示出每个进程(正在运行进程和等待进程)的进程名、到达时刻、开始运行时刻、结束运行时刻、现在系统时刻、进程状态、所需运行时间。

指出进程到达顺序与调度顺序,并计算每个进程的周转时间和带权周转时间。

3 .数据及算法分析

分析SJF算法的优缺点。

利用写好的非抢占SJF算法,思考抢占式SJF和优先级调度算法应该怎样写?

4.完成实验报告

对相关代码和过程进行保存,并对相关实验结果截图展示在实验报告中,其中代码部分需粘贴在实验报告中不要截图请直接贴代码。

四、实验结果展示

1.实验参考结果(1)

2.实验参考代码(2)

#include<stdio.h>
//SJF调度算法
struct process {
	//进程名称
	char name[10];
	//进程id
	int id;
	//进程到达时间
	int ArriveTime;
	//进程开始时间
	int StartTime;
	//进程运行时间
	int RunTime;
	//进程完成时间
	int FinishiTime;
	//进程周转时间
	float TurnTime;
	//带权周转时间
	float WaitTime;
	//进程状态
	int State;
}PCB[25];

int main() {
	//模拟数据生成
	int num, i, j;
	int m;
	int n;
	printf("请输入进程数:");
	scanf("%d", &num);
	if (num < 5 || num>25)
	{
		printf("您的输入无效,默认将进程数设置为5\n");
		num = 5;
	}
	for (i = 0; i < num; i++)
	{
		printf("请输入第%d个进程的id、name、到达时间、所需运行时间。(数据间用空格间隔)\n", i + 1);
		scanf("%d %s %d %d", &PCB[i].id, PCB[i].name, &PCB[i].ArriveTime, &PCB[i].RunTime);
	}

	//比较出初始到达时间
	struct process t1;
	for (i = 0; i < num - 1; i++)
	{
		for (j = i + 1; j < num; j++)
		{
			if (PCB[i].ArriveTime > PCB[j].ArriveTime)
			{
				t1 = PCB[i];
				PCB[i] = PCB[j];
				PCB[j] = t1;
			}
		}
	}

	//挑选出运行时间候选圈内到达的进程,并比较运行时间
	struct process t2;
	for (i = 0; i < num - 1; i++)
	{
		for (j = i + 1; j < num; j++)
		{
			//比较运行时间与到达时间,候选圈
			if (PCB[i].RunTime < PCB[j].ArriveTime)
{
				//比较运行时间
				for (m = i + 1; m < j; m++)
				{
					for (n = m + 1; n < j + 1; n++)
					{
						if (PCB[m].RunTime > PCB[n].RunTime)
						{
							t2 = PCB[m];
							PCB[m] = PCB[n];
							PCB[n] = t2;
						}
					}
				}
			}
		}
	}

	//比较初始运行时间
	struct process t3;
	for (i = 0; i < num - 1; i++)
	{
		for (j = i + 1; j < num; j++)
		{
			if (PCB[i].ArriveTime == PCB[j].ArriveTime)
			{
				if (PCB[i].RunTime > PCB[j].ArriveTime)
				{
					t3 = PCB[i];
					PCB[i] = PCB[j];
					PCB[j] = t3;
				}
			}
		}
	}

	//进程开始运转
	printf("\n");
	for (i = 0; i < num; i++)
	{
		printf("进程%s开始运转......\n", PCB[i].name);
	}

	//计算完成、运转时间
	int NowTime = 0;
for (i = 0; i < num; i++)
	{
		//开始时间=到达时间
		PCB[i].StartTime = NowTime;

		//完成时间=开始时间+运转时间
		PCB[i].FinishiTime = PCB[i].StartTime + PCB[i].RunTime;

		//周转时间=结束时间-到达时间
		PCB[i].TurnTime = PCB[i].FinishiTime - PCB[i].ArriveTime;

		//带权运转时间=周转时间/运行时间
		PCB[i].WaitTime = PCB[i].TurnTime / PCB[i].RunTime;

		//当前时间=完成时间
		NowTime = PCB[i].FinishiTime;

	}

	//显示进程表格
	printf("\n");
	printf(" id 进程名 到达时间 开始时间 结束时间 周转时间 带权周转时间\n");
	for (i = 0; i < num; i++)
	{
		printf("%5d %5s %5d %8d %8d        %.6f    %.6f\n", PCB[i].id, PCB[i].name, PCB[i].ArriveTime, PCB[i].StartTime, PCB[i].FinishiTime, PCB[i].TurnTime, PCB[i].WaitTime);
	}

	return 0;
}

3.实验参考结果(2)

  4.实验代码(2)

//非抢占式短作业优先调度算法模拟 

#include "stdio.h"

typedef struct 
{
//struct PCB* link;     //PCB链表指针
char name;          //进程名
int id;             //进程id
int atime;         //进程到达时间
int stime;         //进程开始时间
int runtime;       //进程运行时间
int ftime;         //进程完成时间
float total;           //周转时间
float welght;        //带权周转时间(周转系数)
int status;          //进程状态
}PCB;
enum  bool{false = 0,true = 1 };
void init(PCB p[],int n){//初始化进程
	//printf("请输入进程个数\n");
	//scanf("%d",&n);
	int i;
	for(i=0;i<n;i++){
		printf("请输入第%d个进程的id、name、到达时间、所需运行时间。数据间用空格间隔\n",i+1);
		scanf("%d %c %d %d",&p[i].id,&p[i].name,&p[i].atime,&p[i].runtime);
		p[i].status=0;//0代表已输入,可能还未到达系统
	}
}
void swap(PCB *p,PCB *q){//交换p和q的值 
	PCB temp;
	temp=*p;
	*p=*q;
	*q=temp;	
}
void sort(PCB p[],int n){//对进程按照到达时间先后及运行时间长短排序
	int i,j;
	enum bool change;
	//PCB temp;
	for(i=0;i<n;i++){
		change = false;
		for(j=0;j<n-i-1;j++){
			if(p[j].atime>p[j+1].atime){
				swap(&p[j],&p[j+1]);		
			}
	//若到达时间一致,应再比较运行时间
			if(p[j].atime==p[j+1].atime){
				if(p[j].runtime>p[j+1].runtime)
					swap(&p[j],&p[j+1]);		
			}
		}
		if(!change)
		     return ;
	}
	
}

int select(PCB p[],int n,int k){//选出已到达系统但运行时间最短的进程
	int time;
	int i,j=k;
	//多个进程已到达系统选运行时间最短的 
	time=p[k].runtime;
	
	for(i=1;i<n;i++){
		if(p[i].status==1 && p[i].runtime<time){
			time=p[i].runtime;
			j=i;		
		}
	}

	return j;
}

void process(PCB p[],int n){//开始进程调度
	int i,j,k=0,time,count=0;
	time=p[0].atime+p[0].runtime;//time表示当前时间
	printf("进程%c开始运行……\n",p[k].name);
	p[k].status=2;//运行完成状态
	p[k].ftime=time;
	p[k].stime=p[k].atime;
	p[k].total=p[k].ftime-p[k].atime;
	p[k].welght=p[k].total/p[k].runtime;
	for(i=1;i<n;i++){//循环处理n-1个进程
		//判断下一个进程是否达到系统。
		if(p[i].atime>time)//当前进程的到达时间比系统时间大,则进程还未到达系统,系统时间直接置为下一个进程达到时间
			time=p[i].atime;
		for(j=0;j<n;j++){//找到所有已到达系统的进程 
			//if(count==n-1) break;//如果剩余n-1个进程已全部到达系统,则不需要再检测
			if(p[j].status!=2 && p[j].atime<=time){
				//count++;
				p[j].status=1;//代表已到达系统,等待调度,就绪;
			}
		}
		for(j=0;j<n;j++){//找到第一个等待运行进程在数组中的下标	
			if(p[j].status==1 ){
				count=j;
				break;
			}	
		}
		k=select(p,n,count);//选出已到达系统但运行时间最短的进程
		time=time+p[k].runtime;//time表示当前时间
		printf("进程%c开始运行……\n",p[k].name);
		p[k].status=2;//运行完成状态
		p[k].ftime=time;
		p[k].stime=p[k].ftime-p[k].runtime;
		p[k].total=p[k].ftime-p[k].atime;
		p[k].welght=p[k].total/p[k].runtime;
		
	}
	
	
}

void print(PCB p[],int n){
	int i;
	printf("id   进程名  到达时间  运行时间  开始时间  结束时间   周转时间  带权周转时间\n");
	for(i=0;i<n;i++){
		printf("%4d %4c %8d %8d %8d %12d %12f %12f\n",p[i].id,p[i].name,p[i].atime,p[i].runtime,p[i].stime,p[i].ftime,p[i].total,p[i].welght);
	}
}



int main(){
PCB p[6];
int n=0;
printf("请输入进程个数\n");
scanf("%d",&n);
init(p,n); 
sort(p,n);
process(p,n);
print(p,n);
return 1;
}

五、实验总结和思考

       编写代码时,我发现自己对C语言的基础知识已经不太熟悉了,并且,自己对SJF的算法没有进行过深入的探究和学习。因此,我要多找时间去巩固C语言基础知识,多研究SJF算法等方面的内容,认真学习优秀的教程和代码,尽量在电脑上进行相关实践,使自己能够熟练地掌握这方面编程知识。

        而且,当代码运行出现问题时,在经过自己的认真思考和资料查找之后,应主动与同学还有老师进行交流,多制作出几套方案,以锻炼自己解决问题和与他人协作的能力。

        总之,学无止境,我还有许许多多方面的能力都还需要提高,今后我会更加严格要求自己,加强自己的学习能力。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值