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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40695551/article/details/84920964

目的:陆续整理近一年的学习收获

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

一:概念

  • 先来先服务FCFS调度算法:最简单的调度算法,既可以用于作业调度 ,也可以用于程序调度,当作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”,直到该进程运行到完成或发生某事件堵塞后,进程调度程序才将处理机分配给其他进程。

        有利于长作业(进程)而不利于短作业(进程)

        有利于CPU繁忙型作业(进程)而不利于I/O繁忙型作业(进程)

  • 短作业优先SJF进程调度算法:以作业长短来确定优先级,作业越短优先级越高,作业的长短用作业所需的运行时间来衡量,此算法一样也可以用做进程调度,它将从外存的作业后备队列中选择若干个估计运行时间最短的作业,优先将它们调入内存运行

       比FCFS改善平均周转时间和平均带权周转时间,缩短作业的等待时间;

       对长作业非常不利,可能长时间得不到执行;

       未能依据作业的紧迫程度来划分执行的优先级;

       难以准确估计作业(进程)的执行时间,从而影响调度性能。

二:程序设计

  • 定义进程结构体
typedef struct{
    char ID;//进程名字
    int ArrivalTime;//到达时间
    int ServiceTime;//服务时间
    int FinishTime;//完成时间
    int ExecuteTime;//各进程的开始执行时间
    int WholeTime;//周转时间
    double WeightWholeTime;//带权周转时间
}PRO;
  • 主要函数
void Input();//输入进程数、各进程到达、服务时间
void sortArrivalTime();//根据达时间排序
void sortServiceTime();//已到达的进程服务时间排序
void calculationInitTime(int i);//计算第一个进程的各个时间
void calculationTime(int i);//计算
void display(int b);//输出
void outTimeState(int b);//输出各时间状态
void chooseAlgorithm();//选择算法
void FCFS();
void SJF();
  • 算法详细设计

FCFS:

void FCFS(){
    int i;


    //根据达时间排序
    sortArrivalTime();

    //FCFS计算各时间
    calculationInitTime(0);
    for(i=1;i<n;i++) {
        calculationTime(i);
        SumWT_FCFS += pro[i].WholeTime;
        SumWWT_FCFS += pro[i].WeightWholeTime;
    }
    SumWT_FCFS += pro[0].WholeTime;
    SumWWT_FCFS += pro[0].WeightWholeTime;
    AverageWT_FCFS = (double)SumWT_FCFS/(double)n;
    AverageWWT_FCFS = (double)SumWWT_FCFS/(double)n;

    //FCFS输出各时间
    display(n);

    //FCFS输出各时间状态
    outTimeState(n);
}

SJF:

void SJF(){
    int i;


    //根据达时间排序
    sortArrivalTime();

    //SJF计算各时间
    calculationInitTime(0);

    for(i=1;i<n;i++) {
   sortServiceTime();
        calculationTime(i);
        SumWT_SJF += pro[i].WholeTime;
        SumWWT_SJF += pro[i].WeightWholeTime;
    }
    SumWT_SJF += pro[0].WholeTime;
    SumWWT_SJF += pro[0].WeightWholeTime;
    AverageWT_SJF = (double)SumWT_SJF/(double)n;
AverageWWT_SJF = (double)SumWWT_SJF/(double)n;

    //SJF输出各时间
display(n);

    //SJF输出各时间状态
    outTimeState(n);
}

三:实验结果

FCFS

SJF

四:实验源码

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

#define MaxNum 100//允许的最大进程数
typedef struct{
    char ID;//进程名字
    int ArrivalTime;//到达时间
    int ServiceTime;//服务时间
    int FinishTime;//完成时间
    int ExecuteTime;//各进程的开始执行时间
    int WholeTime;//周转时间
    double WeightWholeTime;//带权周转时间
}PRO;

static int n=0;//进程数
static PRO pro[100];  //进程结构体
static PRO temp;  //进程结构


static int choose;//算法选择
static double AverageWT_FCFS=0,AverageWT_SJF=0;//FCFS和SJF的平均周转时间
static double AverageWWT_FCFS=0,AverageWWT_SJF=0;//FCFS和SJF的平均带权周转时间
static int SumWT_FCFS=0,SumWT_SJF=0;//FCFS、SJF中的周转时间总和
static double SumWWT_FCFS=0,SumWWT_SJF=0;;//FCFS、SJF中的带权周转时间总和

void Input();//输入进程数、各进程到达、服务时间
void sortArrivalTime();//根据达时间排序
void sortServiceTime();//已到达的进程服务时间排序
void calculationInitTime(int i);//计算第一个进程的各个时间
void calculationTime(int i);//计算
void display(int b);//输出
void outTimeState(int b);//输出各时间状态
void chooseAlgorithm();//选择算法
void FCFS();
void SJF();





int main(){
    int i,j;
    //初始化
    for(i=0;i<MaxNum;i++) {
        pro[i].ID = i+65;//自动将进程名字顺序编号为A、B、C、D、E等
    }
    Input();
    chooseAlgorithm();

    return 0;
}

//输入进程数、各进程到达、服务时间
void Input() {
    cout<<"请输入作业(进程)个数n:";
	cin>>n;
  cout<<"请分别输入每个进程的到达时间(空格隔开):"<<endl;
	for (int i=0;i<n;i++)
	{
		cin>>pro[i].ArrivalTime;
	}

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

	cout<<endl<<"------------------------------------"<<endl;
}

//根据达时间排序
void sortArrivalTime() {
    int i,j;
     for(i=0;i<n;i++) {
        for(j=i+1;j<n;j++) {
            if(pro[i].ArrivalTime > pro[j].ArrivalTime) {
                temp = pro[i];
                pro[i] = pro[j];
                pro[j] = temp;
            }
        }
    }
}

//已到达的进程服务时间排序
void sortServiceTime() {
    int i,j;
     for(i=1;i<n;i++) {
        for(j=i+1;j<n;j++) {
            if(pro[i].ServiceTime > pro[j].ServiceTime) {
                temp = pro[i];
                pro[i] = pro[j];
                pro[j] = temp;
            }
        }
    }

}

//计算第一个进程的各个时间
void calculationInitTime( int i) {
    pro[i].FinishTime = pro[i].ArrivalTime + pro[i].ServiceTime;
    pro[i].WholeTime = pro[i].FinishTime- pro[i].ArrivalTime;
    pro[i].WeightWholeTime = (double)pro[i].WholeTime/(double)pro[i].ServiceTime;
    pro[i].ExecuteTime = pro[i].ArrivalTime;
}

//计算完成时间、周转时间、带权周转时间、开始执行时间
void calculationTime(int i) {
    if(pro[i].ArrivalTime <= pro[i-1].FinishTime) {
        pro[i].FinishTime = pro[i-1].FinishTime + pro[i].ServiceTime;
        pro[i].ExecuteTime = pro[i-1].FinishTime;
    }
    else {
        pro[i].FinishTime= pro[i].ArrivalTime + pro[i].ServiceTime;
        pro[i].ExecuteTime= pro[i].ArrivalTime;
    }
    pro[i].WholeTime = pro[i].FinishTime - pro[i].ArrivalTime;
    pro[i].WeightWholeTime = (double)pro[i].WholeTime/(double)pro[i].ServiceTime;
}

//输出ID、到达时间、服务时间、完成时间、周转时间、带权周转时间、开始执行时间、周转时间总和、带权周转时间总和、平均周转时间、平均带权周转时间
void display(int b) {
    cout<<"ID"<<"\t"<<"到达时间"<<"\t"<<"服务时间"<<"\t"<<"完成时间"<<"\t"<<"周转时间"<<"\t"<<"带权周转时间"<<"\t"<<"开始执行时间"<<endl;
    int i;
    for(i=0;i<b;i++) {
        cout<<pro[i].ID<<"\t"<<pro[i].ArrivalTime<<"\t"<<"\t"<<pro[i].ServiceTime<<"\t"<<"\t"<<pro[i].FinishTime<<"\t";
       cout<<"\t"<<pro[i].WholeTime<<"\t"<<"\t"<<setprecision(2)<<pro[i].WeightWholeTime<<"\t"<<"\t"<<pro[i].ExecuteTime<<endl;
    }
    if(choose==1){
        cout<<endl<<"FCFS周转时间总和: "<<SumWT_FCFS<<endl<<"FCFS带权周转时间总和: ";
        cout<<SumWWT_FCFS<<endl<<"FCFS平均周转时间: ";
        cout<<AverageWT_FCFS<<endl<<"FCFS带权平均周转时间: ";
        cout<<AverageWWT_FCFS<<endl;
    }
    else{
        cout<<endl<<"SJF周转时间总和: "<<SumWT_SJF<<endl<<"SJF带权周转时间总和: ";
        cout<<SumWWT_SJF<<endl<<"SJF平均周转时间: ";
        cout<<AverageWT_SJF<<endl<<"SJF带权平均周转时间: ";
        cout<<AverageWWT_SJF<<endl;
    }

}

//输出各时间状态
void outTimeState(int b) {
    int i,j;
    cout<<endl;
    for(i=0;i<=pro[b-1].FinishTime;i++) {
        cout<<"时刻 "<<i<<": ";
        for(j=0;j<b;j++) {
            if(pro[j].ArrivalTime == i && pro[j].ExecuteTime== i)
                cout<<"ID "<<pro[j].ID<<" 进程到达并且执行, ";
            else if(pro[j].ArrivalTime == i)
                cout<<"ID "<<pro[j].ID<<" 到达, ";
            else if(pro[j].ExecuteTime == i)
                cout<<"ID "<<pro[j].ID<<" 开始执行, ";
            else if(pro[j].FinishTime == i)
                cout<<"ID "<<pro[j].ID<<" 完成, ";
        }
        cout<<endl;
    }
}

void FCFS(){
    int i;


    //根据达时间排序
    sortArrivalTime();

    //FCFS计算各时间
    calculationInitTime(0);
    for(i=1;i<n;i++) {
        calculationTime(i);
        SumWT_FCFS += pro[i].WholeTime;
        SumWWT_FCFS += pro[i].WeightWholeTime;
    }
    SumWT_FCFS += pro[0].WholeTime;
    SumWWT_FCFS += pro[0].WeightWholeTime;
    AverageWT_FCFS = (double)SumWT_FCFS/(double)n;
    AverageWWT_FCFS = (double)SumWWT_FCFS/(double)n;

    //FCFS输出各时间
    display(n);

    //FCFS输出各时间状态
    outTimeState(n);
}

void SJF(){
    int i;


    //根据达时间排序
    sortArrivalTime();

    //SJF计算各时间
    calculationInitTime(0);

    for(i=1;i<n;i++) {
   sortServiceTime();
        calculationTime(i);
        SumWT_SJF += pro[i].WholeTime;
        SumWWT_SJF += pro[i].WeightWholeTime;
    }
    SumWT_SJF += pro[0].WholeTime;
    SumWWT_SJF += pro[0].WeightWholeTime;
    AverageWT_SJF = (double)SumWT_SJF/(double)n;
AverageWWT_SJF = (double)SumWWT_SJF/(double)n;

    //SJF输出各时间
display(n);

    //SJF输出各时间状态
    outTimeState(n);
}

void chooseAlgorithm()
{
	cout<<"请选择算法“1-FCFS,2-SJF”"<<endl;

	cin>>choose;
	cout<<endl;
	if (choose==1)
	{
		FCFS();
	}
		else if(choose==2)
		{
			SJF();
		}
	else
	{
		cout<<"请输入正确的选择“1-FCFS,2-SJF”"<<endl;
		cout<<"------------------------------------"<<endl;
		chooseAlgorithm();  //递归
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40695551/article/details/84920964