《操作系统》实验一:先来先服务FCFS和短作业优先SJF进程调度算法

实验题目先来先服务FCFS和短作业优先SJF进程调度算法

实验学时】:4学时

实验目的】 

通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变、进程调度的策略及对系统性能的评价方法。

实验内容

问题描述:

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

程序要求如下:

1)进程个数n;每个进程的到达时间T1, … ,Tn和服务时间S1, … ,Sn;选择算法1-FCFS,2-SJF。

2)要求采用先来先服务FCFS和短作业优先SJF分别调度进程运行,计算每个进程的周转时间,带权周转时间,并且计算所有进程的平均周转时间,带权平均周转时间;

3)输出:要求模拟整个调度过程,输出每个时刻的进程运行状态,如“时刻3:进程B开始运行”等等;

4)输出:要求输出计算出来的每个进程的周转时间,带权周转时间,所有进程的平均周转时间,带权平均周转时间。

核心算法

#include <iomanip>
#include <iostream>
#include <iomanip>
using namespace std;

#define MaxNum 100


//相同的数组下标对应同一个进程的信息
int  ArrivalTime[MaxNum];  //到达时间
int  ServiceTime[MaxNum];  //服务时间
int  FinishTime[MaxNum];   //完成时间
int  WholeTime[MaxNum];    //周转时间
double  WeightWholeTime[MaxNum];      //带权周转时间
double AverageWT_FCFS, AverageWT_SJF;  //FCFS算法的平均周转时间,SJF算法的平均周转时间
double AverageWWT_FCFS, AverageWWT_SJF; //FCFS算法的平均带权周转时间,SJF算法的平均带权周转时间

bool isFinished_FCFS[MaxNum];
bool isFinished_SJF[MaxNum];

static int n;

void Initial()  //确定进程个数后再初始化
{
	cout << "请输入作业(进程)个数n=";
	cin >> n;

	for (int i = 0;i < n;i++)
	{
		ArrivalTime[i] = 0;
		ServiceTime[i] = 0;
		FinishTime[i] = 0;
		WholeTime[i] = 0;
		WeightWholeTime[i] = 0;
		AverageWT_FCFS = 0;
		AverageWT_SJF = 0;
		AverageWWT_FCFS = 0;
		AverageWWT_SJF = 0;
		isFinished_FCFS[i] = false;
		isFinished_SJF[i] = false;
	}
}

void input()
{
	cout << "请分别输入每个进程的到达时间:" << endl;
	for (int i = 0;i < n;i++)
	{
		cin >> ArrivalTime[i];
	}

	cout << "请分别输入每个进程的服务时间:" << endl;
	for (int i = 0;i < n;i++)
	{
		cin >> ServiceTime[i];
	}

	//输出用户输入的信息
	cout << "******************************************************" << endl;
	cout << "用户输入的进程个数n=" << n << endl;

	cout << "用户输入的到达时间分别为:" << endl;
	for (int i = 0;i < n;i++)
	{
		cout << ArrivalTime[i] << " ";
	}
	cout << endl;

	cout << "用户输入的服务时间分别为:" << endl;
	for (int i = 0;i < n;i++)
	{
		cout << ServiceTime[i] << " ";
	}
	cout << endl << "******************************************************" << endl;
}

int get_firstProcess()
{
	int first = MaxNum;
	for (int i = 0;i < n;i++)
	{
		if (ArrivalTime[i] <= ArrivalTime[first])
		{
			first = i;
		}
	}
	return first;
}

void display()
{
	cout << "******************************************************" << endl;
	cout << "进程相关信息如下:" << endl;
	cout << setw(10) << "进程名(ID)" << " ";
	cout << setw(10) << "到达时间" << " ";
	cout << setw(10) << "服务时间" << " ";
	cout << setw(10) << "完成时间" << " ";
	cout << setw(10) << "周转时间" << " ";
	cout << setw(10) << "带权周转时间" << endl;
	for (int i = 0;i < n;i++)
	{
		cout << setw(10) << i + 1 << " ";
		cout << setw(10) << ArrivalTime[i] << " ";
		cout << setw(10) << ServiceTime[i] << " ";
		cout << setw(10) << FinishTime[i] << " ";
		cout << setw(10) << WholeTime[i] << " ";
		cout << setw(10) <<setiosflags(ios::fixed)<<setprecision(2)<< WeightWholeTime[i] << " " << endl;
	}
}

void FCFS()
{
	/*
		1. 找到最先到达的进程的坐标,并计算相关信息
		2. 依次找到接下去到达的进程
	*/

	int startWorkTime = 0;  //表示开始执行时间 = 当前进程之前的所有服务时间之和
	int first = get_firstProcess();  //获得第一个进程

	isFinished_FCFS[first] = true;
	FinishTime[first] = ArrivalTime[first] + ServiceTime[first];
	startWorkTime += ServiceTime[first];   //下一个进程的开始执行时间
	WholeTime[first] = FinishTime[first] - ArrivalTime[first];   //周转时间 = 完成时间 - 到达时间
	WeightWholeTime[first] = WholeTime[first] / ServiceTime[first]; //带权周转时间 = 周转时间/服务时间

	//接下去的进程
	int nextProcess = n; //初始化下一个进程的下标超出界限

	for (int i = 1;i < n;i++)
	{
		nextProcess = n;  //每次对下一个进程的下标进行更新
		for (int j = 0;j < n;j++)
		{
			if (!isFinished_FCFS[j])  //表示当前进程还未完成相关信息的计算
			{
				if (ArrivalTime[j] <= startWorkTime)  //满足到达时间小于等于开始执行时间的情况下
				{
					if (nextProcess == n)
					{
						nextProcess = j;
					}
					else
					{
						if (ArrivalTime[nextProcess] > ArrivalTime[j])  //筛选出最先到达的进程
						{
							nextProcess = j;    //获得当前进程中:最先到达的进程
						}
					}
				}
			}
		}//for(j)
		//获得当前需要处理的进程nextProcess后,对相关信息进行计算
		isFinished_FCFS[nextProcess] = true;
		FinishTime[nextProcess] = ServiceTime[nextProcess] + startWorkTime;
		startWorkTime += ServiceTime[nextProcess];  //获得下一个进程对应的“开始执行时间”
		WholeTime[nextProcess] = FinishTime[nextProcess] - ArrivalTime[nextProcess];
		WeightWholeTime[nextProcess] = (double)WholeTime[nextProcess] / ServiceTime[nextProcess];

	}//for(i)

	//计算平均周转时间和平均带权周转时间
	double totalWT = 0;
	double totalWWT = 0;
	for (int i = 0;i < n;i++)
	{
		totalWT += WholeTime[i];
		totalWWT += WeightWholeTime[i];
	}
	AverageWT_FCFS = totalWT / n;
	AverageWWT_FCFS = totalWWT / n;

	//输出检测
	display();
	cout << "平均周转时间=" <<setiosflags(ios::fixed)<<setprecision(2)<< AverageWT_FCFS << endl;
	cout << "平均带权周转时间=" <<setiosflags(ios::fixed)<<setprecision(2)<< AverageWWT_FCFS << endl;
	cout << "******************************************************" << endl;
}

void SJF()
{
	//与SCSF类似,相同的方法获得第一个进程
	int startWorkTime_SJF = 0;  //表示开始执行时间 = 当前进程之前的所有服务时间之和
	//第一个进程的处理
	int first = get_firstProcess();  //获得第一个进程

	isFinished_SJF[first] = true;
	FinishTime[first] = ArrivalTime[first] + ServiceTime[first];
	startWorkTime_SJF += ServiceTime[first];   //下一个进程的开始执行时间
	WholeTime[first] = FinishTime[first] - ArrivalTime[first];   //周转时间 = 完成时间 - 到达时间
	WeightWholeTime[first] = (double)WholeTime[first] / ServiceTime[first]; //带权周转时间 = 周转时间/服务时间

	//获得下一个进程的下标

	int nextProcess_SJF = n;
	for (int i = 1;i < n;i++)
	{
		nextProcess_SJF = n;
		for (int j = 0;j < n;j++)
		{
			if (!isFinished_SJF[j])  //表示相关进程还未完成相关信息的计算
			{
				if (ArrivalTime[j] <= startWorkTime_SJF)  //满足到达时间小于等于开始执行时间
				{
					if (nextProcess_SJF == n)  //为最短运行时作业下标赋初值
					{
						nextProcess_SJF = j;
					}
					else
					{
						if (ServiceTime[nextProcess_SJF] > ServiceTime[j])
						{
							nextProcess_SJF = j;   //获得运行时间最短的作业的下标
						}
					}
				}
			}
		}//for(j)

		//对获得的进程进行处理
		isFinished_SJF[nextProcess_SJF] = true;
		FinishTime[nextProcess_SJF] = ServiceTime[nextProcess_SJF] + startWorkTime_SJF;
		startWorkTime_SJF += ServiceTime[nextProcess_SJF];
		WholeTime[nextProcess_SJF] = FinishTime[nextProcess_SJF] - ArrivalTime[nextProcess_SJF];
		WeightWholeTime[nextProcess_SJF] = (double)WholeTime[nextProcess_SJF] / ServiceTime[nextProcess_SJF];

	}//for(i)

	double totalWT = 0;
	double totalWWT = 0;
	for (int i = 0;i < n;i++)
	{
		totalWT += WholeTime[i];
		totalWWT += WeightWholeTime[i];
	}
	AverageWT_SJF = totalWT / n;
	AverageWWT_SJF = totalWWT / n;

	//输出检测
	display();
	cout << "平均周转时间=" <<setiosflags(ios::fixed)<<setprecision(2)<< AverageWT_SJF << endl;
	cout << "平均带权周转时间=" <<setiosflags(ios::fixed)<<setprecision(2)<< AverageWWT_SJF << endl;
	cout << "******************************************************" << endl;
}

void choose_Algorithm()
{
	cout << "请选择算法“1-FCFS,2-SJF”" << endl;
	int choose;
	cin >> choose;
	if (choose == 1)
	{
		FCFS();
	}
	else if (choose == 2)
	{
		SJF();
	}
	else
	{
		cout << "请输入正确的选择“1-FCFS,2-SJF”" << endl;
		cout << "******************************************************" << endl;
		choose_Algorithm();  //递归调用,实现排除错误的选择也可以继续输入
	}
}



int main()
{
	Initial();
	input();
	choose_Algorithm();
	system("pause");
	return 0;
}

【算法流程图】

 

【实例运行结果截图】

FCFS:(使用作业数据)

 

平均周转时间:13.2

平局带权周转时间:3.69

SJF:(使用作业数据)

平均周转时间:10.2

平局带权周转时间:1.92

【实验心得】

FCFS 和 SJF 大致步骤上都是相同的,唯一的区别就是在选择下一个要执行的进程时,FCFS选择的条件是要到达时间小于等于开始执行的时间且最先到达,而SJF选择的条件是要到达时间小于等于开始执行的时间且服务时间最短。

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

守岁白驹hh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值