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

1.实验目的

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

2.实验内容

问题描述:

设计程序模拟进程的先来先服务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)输出:要求输出计算出来的每个进程的周转时间、带权周转时间、所有进程的平均周转时间以及带权平均周转时间。

实现提示:

用C++语言实现提示:

1)程序中进程调度时间变量描述如下:

static int MaxNum=100;

int  ArrivalTime[MaxNum];

int  ServiceTime[MaxNum];

int  FinishTime[MaxNum];

int  WholeTime[MaxNum];

double  WeightWholeTime[MaxNum];

double AverageWT_FCFS,AverageWT_SJF;

double AverageWWT_FCFS,AverageWWT_SJF;

2)进程调度的实现过程如下:

变量初始化;

接收用户输入n,T1, … ,Tn,S1, … ,Sn;算法选择1-FCFS,2-SJF;

按照选择算法进行进程调度,计算进程的完成时间、周转时间和带权周转时间;

计算所有进程的平均周转时间和平均带权周转时间;

按格式输出调度结果。

实验要求:

1)上机前认真复习FCFS和SJF进程调度调度算法,熟悉进程调度的执行过程;

2)上机时独立编程、调试程序;

3)根据具体实验要求,完成好实验报告(包括实验的目的、内容、要求、源程序、实例运行结果截图、发现的问题以及解决方法)。

3.实验开发环境

CodeBlocks编译器

4.程序代码如下及其算法说明

#include <iostream>

#include <iomanip>

#include <cstdlib>

#define MaxNum 100

using namespace std;



int  ArrivalTime[MaxNum]= {0,1,2,3,4}; //到达时间

int  ServiceTime[MaxNum]= {4,3,5,2,4}; //服务时间

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];   //判断FCFS算法中进程是否被执行

bool isFinished_SJF[MaxNum];    //判断SJF算法中进程是否被执行



static int n=5;



void Initial()  //进行初始化

{

    for (int i=0; i<n; i++)

    {

        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<<"用户输入的进程个数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;

    cout<<endl;



}

//找到第一个进程

int find_firstProcess()

{

    int first = n-1;

    for (int i=0; i<n; i++)

    {

        if (ArrivalTime[i]<=ArrivalTime[first])

        {

            first = i;

        }

    }

    return first;

}



void result()

{

    cout<<endl;

    cout<<setw(10)<<"进程名"<<" ";

    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)<<WeightWholeTime[i]<<" "<<endl;

    }

}



void FCFS()

{

    int startWorkTime = 0;  //表示每个进程开始执行的时间 = 当前进行的进程之前的所有进程的服务时间之和

    int first = find_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]; //带权周转时间 = 周转时间/服务时间



    //找到接下去的进程

    for (int i=1; i<n; i++)

    {

        int 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])  //筛选出最先到达的进程

                        {

                            cout<<ArrivalTime[nextProcess]<<endl;

                            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] = WholeTime[nextProcess]/ServiceTime[nextProcess]; //带权周转时间 = 周转时间/服务时间



    }



    //计算平均周转时间和平均带权周转时间

    double totalWT = 0;

    double totalWWT = 0;

    for (int i=0; i<n; i++)

    {

        totalWT+=WholeTime[i];

        totalWWT+=WeightWholeTime[i];

    }

    AverageWT_FCFS = totalWT/n; //平均周转时间=周转时间之和/进程数n

    AverageWWT_FCFS = totalWWT/n; //平均带权周转时间=带权周转时间/进程数n



    //调用输出函数



    result();

    cout<<"平均周转时间="<<AverageWT_FCFS<<endl;

    cout<<"平均带权周转时间="<<AverageWWT_FCFS<<endl;

    cout<<endl;

}



void SJF()

{

    int startWorkTime_SJF = 0;  //表示开始执行时间 = 当前进程之前的所有服务时间之和

    int first = find_firstProcess();  //获得第一个进程



    isFinished_SJF[first] = true;

    FinishTime[first] = ArrivalTime[first] + ServiceTime[first];

    startWorkTime_SJF += ServiceTime[first];   //下一个进程的开始执行时间

    WholeTime[first] = FinishTime[first] - ArrivalTime[first];   //周转时间 = 完成时间 - 到达时间

    WeightWholeTime[first] = WholeTime[first]/ServiceTime[first]; //带权周转时间 = 周转时间/服务时间



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



    for (int i=1; i<n; i++)

    {

        int nextProcess = n;

        for (int j=0; j<n; j++)

        {

            if (!isFinished_SJF[j])

            {

                if (ArrivalTime[j]<=startWorkTime_SJF)//到达时间小于已经进行的时间

                {

                    if (nextProcess==n)

                    {

                        nextProcess = j;

                    }

                    else

                    {

                        if (ServiceTime[nextProcess]>ServiceTime[j])

                        {

                            nextProcess = j;   //获得运行时间最短的作业的下标

                        }

                    }

                }

            }

        }



        //对获得的进程进行处理

        isFinished_SJF[nextProcess] = true;

        FinishTime[nextProcess] = ServiceTime[nextProcess] + startWorkTime_SJF;

        startWorkTime_SJF += ServiceTime[nextProcess];

        WholeTime[nextProcess] = FinishTime[nextProcess] - ArrivalTime[nextProcess];

        WeightWholeTime[nextProcess] = (double)WholeTime[nextProcess]/ServiceTime[nextProcess];



    }



    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;



    //输出检测

    result();

    cout<<"平均周转时间="<<AverageWT_SJF<<endl;

    cout<<"平均带权周转时间="<<AverageWWT_SJF<<endl;

    cout<<endl;

}

//选择算法

void choose_Way()

{

    cout<<"请选择算法 ①FCFS OR ②SJF"<<endl;

    int way;

    cin>>way;

    if (way==1)

    {

        FCFS();

    }

    else if(way==2)

    {

        SJF();

    }

    else

    {

        cout<<"请选择正确序号”"<<endl;

        cout<<endl;

        choose_Way();//回调函数

    }

}



//调用mian函数

int main()

{

    Initial();

    input();

    choose_Way();

    system("pause");

    choose_Way();

    return 0;

}

代码说明:算法分为对数组初始化Initial(),然后给数组赋值input(),然后用户选择方法choose_way()。

FCFS先来先服务采用的算法如下:

//找到接下去的进程

    for (int i=1; i<n; i++)

    {

        int 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])  //筛选出最先到达的进程

                        {

                            cout<<ArrivalTime[nextProcess]<<endl;

                            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] = WholeTime[nextProcess]/ServiceTime[nextProcess]; //带权周转时间 = 周转时间/服务时间



    }

FCFS思路:首先先排除已经服务过的进程,然后for(i)循环来执行剩下的进程,通过for(i)中的for(j)循环找到剩下未执行的进制中最早到达且到达时间小于已经服务的时间的进程来进行,以此类推依次找到完成剩下的进程

SJF算法如下:

for (int i=1; i<n; i++)

    {

        int nextProcess = n;

        for (int j=0; j<n; j++)

        {

            if (!isFinished_SJF[j])

            {

                if (ArrivalTime[j]<=startWorkTime_SJF)//到达时间小于已经进行的时间

                {

                    if (nextProcess==n)

                    {

                        nextProcess = j;

                    }

                    else

                    {

                        if (ServiceTime[nextProcess]>ServiceTime[j])

                        {

                            nextProcess = j;   //获得运行时间最短的作业的下标

                        }

                    }

                }

            }

        }



        //对获得的进程进行处理

        isFinished_SJF[nextProcess] = true;

        FinishTime[nextProcess] = ServiceTime[nextProcess] + startWorkTime_SJF;

        startWorkTime_SJF += ServiceTime[nextProcess];

        WholeTime[nextProcess] = FinishTime[nextProcess] - ArrivalTime[nextProcess];

        WeightWholeTime[nextProcess] = (double)WholeTime[nextProcess]/ServiceTime[nextProcess];



}

SJF思路:首先先排除已经服务过的进程,然后for(i)循环来执行剩下的进程,通过for(i)中的for(j)循环找到剩下未执行的进制中服务时间最短且到达时间小于已经服务的时间的进程来进行,以此类推依次找到完成剩下的进程

5.调试过程和运行结果

FCFS算法结果如下

 

SJF算法如下

 

### 回答1: 先来先服务FCFS进程调度算法是一种简单的调度算法,按照进程到达的先后顺序进行调度。即先到达的进程先执行,后到达的进程后执行。这种算法的优点是简单易懂,缺点是可能会出现长作业等待时间过长的情况。 作业优先SJF进程调度算法是一种根据进程执行时间长来进行调度的算法。即执行时间的进程先执行,执行时间长的进程后执行。这种算法的优点是可以减少长作业等待时间,缺点是可能会出现作业饥饿的情况。 ### 回答2: 进程调度算法是计算机操作系统中非常重要的一部分,FCFS先来先服务)和SJF作业优先)是其中比较常见的两种算法。下面将分别对两种算法进行介绍及比较。 FCFS算法先来先服务,即按照进入就绪队列的顺序,先进入队列的进程先被执行。该算法的优点是简单易懂,不需要对进程的属性进行过多的分析。但是,该算法存在一个致命的弊端:无法处理作业和长作业混杂的情况,因为如果遇到一个长作业作业就会被迫等待很长时间,导致系统的响应速度变慢。 SJF算法作业优先,即在就绪队列中,选择最作业先执行。该算法的优点是可以尽可能地提高系统的响应速度,保证作业更快地完成。但是该算法也存在一些缺点:由于进程的执行时间不确定,因此难以做出一个准确的预测,如果预测错误,可能会出现长时间的等待,导致系统效率降低。 两种算法的比较:FCFS算法最大的优点是简单易懂,没有太多的计算复杂度,但是对于作业和长作业混杂的情况,无法满足系统性能的要求。而SJF算法虽然能够提高系统的响应速度,并且对于作业友好,但也存在预测困难的问题,也会产生等待的情况。因此,需要根据具体的情况选择适合的算法,如果作业的执行时间能够事先预测,SJF算法是一个很好的选择,否则则可以选择FCFS算法。但是在实际应用中,为了更好地提高系统的性能,一般会采用优先级调度算法,根据进程的属性进行优先级的排序,以此来保证更加合理的进程调度顺序。同时,还可以采用时间片轮转的方法,将长作业进行切割,让多个进程共享CPU,提高系统的处理能力。 ### 回答3: 先来先服务FCFS)是一种最简单的调度算法,也被称为先到先服务或先进先出。该算法的基本原理是按照进程到达的顺序进行调度,即先到来的进程先执行,后到达的进程后执行。FCFS算法适用于进程执行时间相同时,优先级相同的情况。由于该算法的简单性,一般只有在任务队列中的进程个数固定且任务时间相等时才使用。但是,FCFS算法的显著缺陷是无法解决作业等待长作业的问题,因此在实际应用中,FCFS算法很少使用。 作业优先SJF)是一种比FCFS算法更为高效的调度算法,也被称为最作业优先。该算法的基本原理是按照进程需要执行的时间的长来进行调度,即先优先选择需要执行时间较的进程,而不是按照它们到达的顺序来进行调度。SJF算法适用于任务队列中的进程的时间不一致的情况。该算法具有高响应度、高效率和低等待时间的优点,能够降低平均等待时间。但是,该算法也存在着一定的问题,如容易出现饥饿现象(即在系统运行的过程中,某些进程始终无法被调度执行)。因此,通常可以将作业优先算法与其他调度算法一起使用,以避免饥饿现象的出现。 总之,先来先服务作业优先都是进程调度算法中常见的两种,它们各有优缺点,需要根据具体的情况选择合适的算法来保证系统的效率和稳定性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值