处理机调度算法模拟实验——FCFS算法,SJF调度算法

处理机调度算法模拟实验

一、实验目的

本实验模拟在单处理机情况下的处理机调度算法,用某种编程语言实现先来先服务和最短作业优先调度算法的模拟。

二、实验原理

1、先来先服务调度算法原理:
先来先服务调度算法,类似于队列,先进先出,后进后出。

输入进程后依据进程的提交时间进行排序。

1.怎么计算每个作业的运行时间? 运行时间就是作业需要运行的时间。

2.怎么计算每个作业的结束时间?

先维护一个成员变量作为当前时间,

当前时间初始化为第一个作业进入的时间

每进入一个作业,当前时间就加上该作业的 运行时间

每个作业的结束时间就是当前时间。

3.怎么计算周转时间?

周转时间=作业结束时间—作业提交时间。

4.怎么计算平均周转时间?

平均周转时间=周转时间/作业个数。

    2、短作业优先调度算法原理为:
在作业调度中,该算法每完成一个作业,就从后续所有到达队列的作业中找到运转时间最短的一个调入内存,分配必要的资源,创建进程并放入就绪队列。SJF是非抢占式的调度算法,优先照顾短作业,具有较好的性能,降低了平均等待时间,提高作业的吞吐量。但另一方面,由于短作业优先,长作业可能超时间处于等待状态,不能用于实时系统。

先输入所有作业的条件,录入到顺序表中

对所有作业按到达时间排序,将到达时间最小的作业调入内存

然后将剩下作业按运转时间升序排序,依次进入内存作业

结束后输出作业时间,平均周转时间

三、实验要求

  上机前必须认真的做好准备,了解FCFS和短作业优先调度算法原理;
 

四、实验内容

1、问题描述

假设有三个作业,他们的作业号、提交时间、需要运行的时间如下:

作业号

提交时间

需要运行的时间

1

0

6

2

2

4

3

3

2

(1)如果使用FCFS调度算法,请问这三个作业的执行顺序是什么样的,并基于此执行顺序计算它们的周转时间、平均周转 时间,计算后将结果填入下表。

三个作业的执行情况分析(FCFS):

作业执行顺序

提交时间

运行时间

开始时间

结束时间

周转

时间

平均周

转时间

1

0

6

0

6

6

7.6

2

2

4

6

10

8

3

3

2

10

12

9

(2)如果使用短作业优先调度算法,请问这三个作业的执行顺序是什么样的,并基于此执行顺序计算它们的周转时间、平均周转时间,计算后将结果填入下表。

三个作业的执行情况分析(SJF):

作业执行顺序

提交时间

运行时间

开始时间

结束时间

周转

时间

平均周

转时间

1

0

6

0

6

6

7

3

3

2

6

8

5

2

2

4

8

12

10

2、代码设计

用某种编程语言模拟FCFS和SJF调度算法,加深对进程调度算法的认识,并将代码复制粘贴在本段下方。要求程序首先由用户输入要运行的作业数,然后选择进程调度算法,并依次输入各个作业的基本信息,包括作业号、提交作业时间、需要运行的时间,代码会分析整个作业调度执行过程,并计算出各个作业的开始执行时间、结束运行时间、周转时间、平均周转时间。

FCFS算法:

Main类:

package fcfs;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<Work> works = new ArrayList<>(); //储存作业
        System.out.println("请输入作业个数");
        int n = sc.nextInt();
        //把需要进行的作业添加到works
        for (int i = 0; i < n; i++) {
            System.out.println("请输入作业的编号、提交时间、运行时间");
            int id = sc.nextInt();
            int startTime = sc.nextInt();
            int runTime = sc.nextInt();
            Work work = new Work(id,startTime,runTime);
            works.add(work);
        }
        LinkSort(works,0,works.size()-1);
        double time = works.get(0).getStartTime();
        double turnvoerTimeSum=0;
        //每个作业的值
        for (Work work : works) {
            if(time<work.getStartTime()) time = work.getStartTime();
            work.setStartRunTime(time);
            time += work.getRunTime();
            work.setFinalTime(time);
            work.setTurnoverTime(time-work.getStartTime());
            turnvoerTimeSum+=work.getTurnoverTime();
        }
        double turnvoerTimeAverage=turnvoerTimeSum/n;
        System.out.println("编号\t\t\t提交时间\t\t\t开始时间\t\t\t运行时间\t\t\t结束时间\t\t\t周转时间");
        for (Work work : works) {
            workOut(work);
        }
        System.out.println("平均周转时间为:"+turnvoerTimeAverage);

    }
    //根据作业的提交时间进行排序
    public static void LinkSort(ArrayList<Work> works,int l,int r){
        if(l>=r) return ;
        Work x = works.get(l+r>>1);
        int i = l-1,j = r+1;
        while(i<j){
            do i++;while(works.get(i).getStartTime()<x.getStartTime());
            do j--;while(works.get(j).getStartTime()>x.getStartTime());
            Collections.swap(works,i,j);
        }
        LinkSort(works,l,j);
        LinkSort(works,j+1,r);
    }
    public static void workOut(Work work){

        System.out.println(work.getId()+"   "+work.getStartTime()+"   "+work.getStartRunTime()+"   "+work.getRunTime()+"   "+work.getFinalTime()+"   "+work.getTurnoverTime());

    }
}

Work类:

package fcfs;



public class Work {

    private int id;

    private double startTime;

    private double startRunTime;



    public double getStartRunTime() {

        return startRunTime;

    }



    public void setStartRunTime(double startRunTime) {

        this.startRunTime = startRunTime;

    }



    private double runTime;

    private double finalTime;

    private double turnoverTime;



    public double getFinalTime() {

        return finalTime;

    }



    public void setFinalTime(double finalTime) {

        this.finalTime = finalTime;

    }



    public double getTurnoverTime() {

        return turnoverTime;

    }



    public void setTurnoverTime(double turnoverTime) {

        this.turnoverTime = turnoverTime;

    }



    public Work(int id, double startTime, double runTime) {

        this.id = id;

        this.startTime = startTime;

        this.runTime = runTime;

    }



    public int getId() {

        return id;

    }



    public void setId(int id) {

        this.id = id;

    }



    public double getStartTime() {

        return startTime;

    }



    public void setStartTime(double startTime) {

        this.startTime = startTime;

    }



    public double getRunTime() {

        return runTime;

    }



    public void setRunTime(double runTime) {

        this.runTime = runTime;

    }

}

SJF调度算法:

#include <iostream>

#include<algorithm>

using namespace std;

string name;

int reachtime;

int usetime;

double averagewaittime;

int alltime = 0;

class node

{

public:

    int name;//作业名 到达时间 运行时间 开始运行时间 结束运行时间 周转时间 是否运行过

    int reachtime;

    int usetime;

    int starttime;

    int useendtime;

    int waittime;

    bool yn;

};

node* arr = new node[100];

node* brr = new node[100];



void push(int x)

{

    cout << "请输入作业号 进入时间 作业时间" << endl;

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

    {

        cin >> arr[i].name >> arr[i].reachtime >> arr[i].usetime;

        arr[i].yn = 1;

    }

}



bool cmp1(node cs1, node cs2)//重载sort,到达时间 运行时间 作业名

{

    return cs2.reachtime > cs1.usetime;

}



bool cmp2(node cs1, node cs2)

{

    return cs1.usetime < cs2.usetime;

}

bool cmp3(node cs1, node cs2)

{

    return cs1.name < cs2.name;

}

int main()

{

    int x, xcode, i = 1;

    cout << "作业总数为:" << endl;

    cin >> x;

    xcode = x ;

    push(x);

    sort(arr, arr + x, cmp1);

    arr[0].starttime = arr[0].reachtime;

    arr[0].useendtime = arr[0].reachtime + arr[0].usetime;

    arr[0].waittime = arr[0].useendtime - arr[0].reachtime;

    arr[0].yn = 0;

    alltime += arr[0].useendtime;

    sort(arr + 1, arr + x, cmp2);

    while (xcode-1)

    {

        if (arr[i].reachtime <= alltime && arr[i].yn == 1)

        {

            arr[i].starttime = alltime;

            arr[i].useendtime = arr[i].usetime + alltime;

            arr[i].waittime = arr[i].useendtime - arr[i].reachtime;

            alltime = arr[i].useendtime;

            xcode--;

            i++;

        }

        else if (arr[i].reachtime > alltime && arr[i].yn == 1)

        {

            alltime = arr[i].reachtime;

            arr[i].useendtime = arr[i].usetime + alltime;

            arr[i].waittime = arr[i].usetime;

            arr[i].starttime = alltime;

            alltime = arr[i].useendtime;

            xcode--;

            i++;

        }

        else if (arr[i].yn == 0)

        {

            i++;

        }

        else if (i >= x)

        {

            i = 1;

        }

    }

    sort(arr, arr + x, cmp3);

    cout << "以下分别为作业号 提交时间 需要运行的时间 开始运行时间 运行结束时间 周转时间" << endl;

    for (int cx = 0; cx < x; cx++)

    {



        cout << arr[cx].name << " " << arr[cx].reachtime << " " << arr[cx].usetime << " " << arr[cx].starttime << " " << arr[cx].useendtime << " " << arr[cx].waittime << endl;

        averagewaittime += arr[cx].waittime;

    }

    averagewaittime = averagewaittime / (double)x;

    cout << "平均周转时间为:" << averagewaittime << endl;

    return 0;

}

3、实验验证

用编写好的代码验证实验内容1中作业的执行情况,看代码运行结果是否与之前的分析计算结果一致,并将执行界面进行截图。

(1)FSFC调度算法

 

(2)SJF调度算法

 

五、实验中遇到的问题及解决方法,以及对作业的自我评价和反思。

FCFS 先来先服务:优点:公平、算法实现简单; 缺点:排在长作业(进程)后面的短作业需要等待很长时间,带权周转时间很大,对短作业来说用户体验不好。即,FCFS算法对长作业有利,对短作业不利

SJF 短作业优先 :优点:“最短的”平均等待时间、平均周转时间。缺点:不公平。对短作业有利,对长作业不利。可能产生饥饿现象。另外,作业/进程的运行时间是由用户提供的,并不一定真实,不一定能做到真正的短作业优先。如果源源不断地有短作业/进程到来,可能使长作业/进程长时间得不到服务,产生“饥饿”现象。如果一直得不到服务,则称为“饿死”

通过这次实验,加深了我对于不同种处理机调度算法的理解,包括不同算法的原理,特点,优缺点等。通过实际的测试用例,让我们对不同调度算法的工作流程和规则更加熟悉。同时,也提升了自己的编程能力,受益匪浅。

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

XSS9

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

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

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

打赏作者

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

抵扣说明:

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

余额充值