操作系统实验代码-先来先服务FCFS和短作业优先SJF进程调度算法-C++实现

一、实验内容

问题描述:

设计程序模拟进程的先来先服务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 <iostream>
#include <queue>
#include<string.h>
#include<algorithm>
#include <stdlib.h>
using namespace std;
float getAvg(float f[5]) {
	float sum = 0.0;
	for (int i = 0; i < 5; i++) {
		sum += f[i];
	}
	return sum/5.0;
}

int main() {
	float arriveTime[5] = {0,1,2,3,4};
	float serveTime[5] = {4,3,5,2,4};
	int c[5]; 
	float finishTime1[5] = {0}, finishTime2[5], circleTime1[5], circleTime2[5], weightTime1[5], weightTime2[5];

	for(int i = 0; i < 5; i++){
		if(i == 0){
			finishTime1[i] = finishTime1[0] + serveTime[0];
			circleTime1[i] = finishTime1[0] - arriveTime[0];
			weightTime1[i] = circleTime1[0] / serveTime[0];
		} else {
			finishTime1[i] = finishTime1[i-1] + serveTime[i];
			circleTime1[i] = finishTime1[i] - arriveTime[i];
			weightTime1[i] = circleTime1[i] / serveTime[i];

		}
	}

	for(int i = 0; i < 5; i++) {
		if(i == 0) {
			finishTime2[i] = finishTime2[0] + serveTime[0];
			circleTime2[i] = finishTime2[0] - arriveTime[0];
			weightTime2[i] = circleTime2[0] / serveTime[0];

		} else {
			float temp = serveTime[i];
			int j, minIndex;
			//获取当前服务时间最短的进程下标 
			for(j = 1; j < 5; j++) {
				temp = min(serveTime[j], temp);
				if(serveTime[j] <= temp ) {
					minIndex = j;
				} 
			}
			c[i] = minIndex;
			finishTime2[i] = finishTime2[i-1] + serveTime[minIndex];
			circleTime2[i] = finishTime2[i] - arriveTime[minIndex];
			weightTime2[i] = circleTime2[i] / serveTime[minIndex];
			//将服务结束的进程服务时间设为无穷大 
			serveTime[minIndex] = 9999;
		}
	}
	
	cout<<"FCFS算法"<<endl<<"完成时间:";
	for(int i = 0; i < 5; i++) {
		cout<<finishTime1[i]<<"  ";
	}
	cout<<endl<<"周转时间:";
	for(int i = 0; i < 5; i++) {
		cout<<circleTime1[i]<<"  ";
	}
	cout<<endl<<"带权周转时间:";
	for(int i = 0; i < 5; i++) {
		cout<<weightTime1[i]<<"  ";
	}
	cout<<endl<<"平均周转时间:"<<getAvg(circleTime1)<<endl;
	cout<<"平均带权周转时间:"<<getAvg(weightTime1)<<endl;

	
	cout<<endl<<endl<<"SJF算法"<<endl<<"完成时间:";
	for(int i = 0; i < 5; i++) {
		cout<<finishTime2[c[5-i]]<<"  ";
	}
	cout<<endl<<"周转时间:";
	for(int i = 0; i < 5; i++) {
		cout<<circleTime2[c[5-i]]<<"  ";
	}
	cout<<endl<<"带权周转时间:";
	for(int i = 0; i < 5; i++) {
		cout<<weightTime2[c[5-i]]<<"  ";
	}
	cout<<endl<<"平均周转时间:"<<getAvg(circleTime2)<<endl;
	cout<<"平均带权周转时间:"<<getAvg(weightTime2)<<endl;
	system("pause");
	return 0;
} 

三、代码说明

1.定义输入数据

float arriveTime[5] = {0,1,2,3,4};

float serveTime[5] = {4,3,5,2,4};

2.定义进程相关变量

float finishTime1[5] = {0}, finishTime2[5], circleTime1[5], circleTime2[5], weightTime1[5], weightTime2[5];

变量说明

finishTime1

FCFS算法完成时间

finishTime2

SJF算法完成时间

circleTime1

FCFS算法周转时间

circleTime2

SJF算法周转时间

weightTime1

FCFS算法带权周转时间

weightTime2

SJF算法带权周转时间

3.计算FCFS算法中的完成时间、周转时间和带权周转时间。

其中,对于循环第一次的完成时间需要特殊处理,时间复杂度为O(n)

for(int i = 0; i < 5; i++){

       if(i == 0){

           finishTime1[i] = finishTime1[0] + serveTime[0];

           circleTime1[i] = finishTime1[0] - arriveTime[0];

           weightTime1[i] = circleTime1[0] / serveTime[0];

       } else {

           finishTime1[i] = finishTime1[i-1] + serveTime[i];

           circleTime1[i] = finishTime1[i] - arriveTime[i];

           weightTime1[i] = circleTime1[i] / serveTime[i];



       }

    }

4.计算SJF算法中的完成时间、周转时间和带权周转时间。

其中,对于循环第一次的完成时间需要特殊处理。

需要注意的是,SJF算法需要让服务时间最短的进程优先进入队列,因此需要内嵌循环,计算每一轮服务时间最短的进程。因此,时间复杂度为O(n2).

for(int i = 0; i < 5; i++) {

       if(i == 0) {

           finishTime2[i] = finishTime2[0] + serveTime[0];

           circleTime2[i] = finishTime2[0] - arriveTime[0];

           weightTime2[i] = circleTime2[0] / serveTime[0];



       } else {

           float temp = serveTime[i];

           int j, minIndex;

           //获取当前服务时间最短的进程下标

           for(j = 1; j < 5; j++) {

              temp = min(serveTime[j], temp);

              if(serveTime[j] <= temp ) {

                  minIndex = j;

              }

           }

           c[i] = minIndex;

           finishTime2[i] = finishTime2[i-1] + serveTime[minIndex];

           circleTime2[i] = finishTime2[i] - arriveTime[minIndex];

           weightTime2[i] = circleTime2[i] / serveTime[minIndex];

           //将服务结束的进程服务时间设为无穷大

           serveTime[minIndex] = 9999;

       }

    }

5.输出FCFS算法结果

cout<<"FCFS算法"<<endl<<"完成时间:";

    for(int i = 0; i < 5; i++) {

       cout<<finishTime1[i]<<"  ";

    }

    cout<<endl<<"周转时间:";

    for(int i = 0; i < 5; i++) {

       cout<<circleTime1[i]<<"  ";

    }

    cout<<endl<<"带权周转时间:";

    for(int i = 0; i < 5; i++) {

       cout<<weightTime1[i]<<"  ";

    }

cout<<endl<<"平均周转时间:"<<getAvg(circleTime1)<<endl;

    cout<<"平均带权周转时间:"<<getAvg(weightTime1)<<endl;

6.输出SJF算法结果

由于在上面的循环中,每一次获取服务时间最小值下标会打乱进程顺序,因此需要用数组c[5]保存下标,从而顺序输出。

cout<<endl<<endl<<"SJF算法"<<endl<<"完成时间:";

    for(int i = 0; i < 5; i++) {

       cout<<finishTime2[c[5-i]]<<"  ";

    }

    cout<<endl<<"周转时间:";

    for(int i = 0; i < 5; i++) {

       cout<<circleTime2[c[5-i]]<<"  ";

    }

    cout<<endl<<"带权周转时间:";

    for(int i = 0; i < 5; i++) {

       cout<<weightTime2[c[5-i]]<<"  ";

    }

    cout<<endl<<"平均周转时间:"<<getAvg(circleTime2)<<endl;

    cout<<"平均带权周转时间:"<<getAvg(weightTime2)<<endl;

四、结果展示

五、总结

        本次实验中,我使用C++代码来模拟FCFS和SJF两种调度算法,根据输入的到达时间和服务时间作为测试数据,实现两种算法的执行顺序,从而得到结果。

    FCFS算法作为较简单的调度算法,其原理比较简单,根据到达时间的先后顺序,决定进程进入队列的优先级,之后每取出一个进程,便依次计算其完成时间、周转时间、带权周转时间,最后得出平均周转时间和平均带权周转时间即可。

    SJF算法需要根据服务时间来决定优先级,服务时间最短的进程,优先进入队列,因此需要在每个进程达到后,获取当前时间最短服务时间的进程,让该进程进入队列。并计算完成时间、周转时间、带权周转时间,最后得出平均周转时间和平均带权周转时间。而且在输出时,要注意顺序不能错乱,根据初始下标输出便得到结果。

    本次实验使我理解了线程的两种调度方式,很明显SJF算法更贴近实际应用,结果也表明SJF的平均周转时间和平均带权周转时间都小于FCFS算法,但实现起来也比FCFS算法要更为复制,两种调度算法各有各的特性,更有利于我理解进程调度的含义。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值