【操作系统】实验——处理机调度算法实现(Java)

实验内容

 编写java程序,实现处理机调度的“先来先服务(FCFS)”算法和“短进程优先(SJF)算法”。
要求:
1)随机输入的进程个数、进程名称、进程提交到系统的时间、进程运行所需时间;
2)通过模拟程序,显示以下信息:a)处理机对进程的调度过程。b)这N个进程的平均周转时间;
3)对实验结果截图并辅以文字对运行结果进行分析。

基础知识简介

1、先来先服务(First Come First Served,FCFS)
 先来先服务(First Come First Served,FCFS)是一种最简单的调度算法,可以用在进程调度和作业调度中。
 它的基本思想是按进程或作业到达的前后顺序进行调度。作业调度中采用该算法时,每次从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源创建进程,然后将进程投入就绪队列。进程调度中采用该算法时,每次从就绪队列中选择一个最先进入该队列的进程,把处理机分配给它,使之投人运行。一直到该进程运行完毕或阻塞后,才让出处理机。
 FCFS算法简单。由于它的处理机调度方式是非剥夺方式,因此操作系统不会强行暂停当前正在运行的进程。
FCFS算法的特点如下:

  • (1)有利于长作业,不利于短作业。
  • (2)有利于处理机繁忙的作业,不利于I/O繁忙的作业。

2、短作业(进程)优先
 短作业(进程)优先(Shortest Job First ,SJF 或 Shortest Process Next,SPN)是指对短作业或短进程优先调度的算法。该算法可分别用于作业调度和进程调度。该算法的设计目标是改进FCFS算法,减少作业或进程的平均周转时间。
 SJF算法要求作业在开始执行之前预计作业的执行时间,对预计执行时间短的作业优先调人内存。
 SPN算法是从就绪队列中选出一个估计运行时间最短的进程,并将处理机分派给它,后来的短进程不能剥夺正在运行的进程。
SJF算法比起FCFS算法有以下优点:

  • (1)改善了平均周转时间和平均带权周转时间,缩短了等待时间。
  • (2)有利于提高系统的吞吐量。

SJF和SPN算法存在以下缺点:

  • (1)对长作业或进程不利。
  • (2)该算法没有考虑作业或进程的紧迫程度,因而不能保证紧迫的作业或进程得到及时 处理或响应。
  • (3)由于作业或进程的执行时间是用户估计的,因而准确性不高,从而影响调度性能
  • (4)如果系统中持续有更短作业或进程出现,可能导致长作业或进程被饿死,即永远得不到执行。

实验过程

1、问题以及设计思路说明:
 分别使用先来先服务算法和短进程优先算法对进程进行调度。在过程中,先设计Process进程类,再创建类实现进程CPU中的进程调度,记录下各个进程的调度时间信息,最后进行计算,得出结果。
2、分析说明:
 方法generateRandomProcesses()帮助进程随机生成到达时间、运行所需时间。先来先服务算法按照进程提交到系统的顺序进行调度。短进程优先算法中,选择运行时间最短的进程进行调度。在先来先服务算法中对各个进程的到达时间进行排序,在短进程优先中对各进程到达时间和运行时间排序,以此决定先后运行的顺序。最后利用方法calculateAverageTurnaroundTime计算各个算法结果的平均周转时间。
3、实验结果:
 两个算法的平均周转时间相比,第二个短进程优先算法的耗时更低。

代码

public class Process {
    public String name;
    public int arrivalTime;//到达时间
    public int burstTime;//运行时间
    public int startTime;//开始时间
    public int completionTime;//完成时间
    

    public Process(String name, int arrivalTime, int burstTime) {
        this.name = name;
        this.arrivalTime = arrivalTime;
        this.burstTime = burstTime;
    }

    public String getName() {
        return name;
    }

    public int getArrivalTime() {
        return arrivalTime;
    }

    public int getBurstTime() {
        return burstTime;
    }

    public int getStartTime() {
        return startTime;
    }

    public void setStartTime(int startTime) {
        this.startTime = startTime;
    }

    public int getCompletionTime() {
        return completionTime;
    }

    public void setCompletionTime(int completionTime) {
        this.completionTime = completionTime;
    }

    @Override
    public String toString() {
        return "Process{" +
                "name='" + name + '\'' +
                ", arrivalTime=" + arrivalTime +
                ", burstTime=" + burstTime +
                ", startTime=" + startTime +
                ", completionTime=" + completionTime +
                '}';
    }
}
import java.util.*;

public class CPU {
    public static void main(String[] args) {
        int numProcesses = 5; // 进程个数
        List<Process> processes = generateRandomProcesses(numProcesses);

        System.out.println("先来先服务算法(FCFS),进程调度顺序:");
        fcfs(processes);
        double avgTurnaroundTime1 = calculateAverageTurnaroundTime(processes);
        System.out.println("\n平均周转时间:" + avgTurnaroundTime1);

        System.out.println("\n短进程优先算法(SJF),进程调度顺序:");
        sjf(processes);

        double avgTurnaroundTime = calculateAverageTurnaroundTime(processes);
        System.out.println("\n平均周转时间:" + avgTurnaroundTime);
    }

    // 生成随机的进程
    public static List<Process> generateRandomProcesses(int numProcesses) {
        List<Process> processes = new ArrayList<>();
        Random random = new Random();
        for (int i = 1; i <= numProcesses; i++) {
            String name = "p" + i;
            int arrivalTime = random.nextInt(10); // 进程提交到系统的时间(0-9之间的随机数)
            int burstTime = random.nextInt(10) + 1; // 进程运行所需时间(1-10之间的随机数)
            Process process = new Process(name, arrivalTime, burstTime);
            processes.add(process);
        }
        return processes;
    }

    // 先来先服务(FCFS)算法
    public static void fcfs(List<Process> processes) {
        Collections.sort(processes, Comparator.comparing(Process::getArrivalTime));

        int preFinished = 0; // 前一个作业的完成时间

//        // 如果第一个作业的到达时间不等于前一个作业的完成时间,就将前一个作业的完成时间定义为当前作业的到达时间
//        if (processes.get(0).arrivalTime != preFinished) {
//            preFinished = processes.get(0).arrivalTime;
//        }
//
//        for (Process value : processes) {
//            // 作业的完成时间为上一个作业的完成时间加当前作业的服务时间
//            value.completionTime = preFinished + value.burstTime;
//            preFinished = value.completionTime;
//        }

        int currentTime = 0;
        for (Process process : processes) {
            process.setStartTime(Math.max(currentTime, process.getArrivalTime()));
            currentTime = process.getStartTime() + process.getBurstTime();
            process.setCompletionTime(currentTime);

            System.out.println("进程 " + process.getName() + " 到达时间: " + process.arrivalTime + " 调度时间:"
                    + process.getStartTime() + "-" + process.getCompletionTime() );
        }
    }

    // 短进程优先(SJF)算法
    public static void sjf(List<Process> processes) {
        Collections.sort(processes, Comparator.comparing(Process::getArrivalTime).thenComparing(Process::getBurstTime));

        int currentTime = 0;
        for (Process process : processes) {
            process.setStartTime(Math.max(currentTime, process.getArrivalTime()));
            currentTime = process.getStartTime() + process.getBurstTime();
            process.setCompletionTime(currentTime);

            System.out.println("进程 " + process.getName() + " 到达时间: " + process.arrivalTime+ " 调度时间:"
                    + process.getStartTime() + "-" + process.getCompletionTime());
        }
    }

    // 计算平均周转时间
    public static double calculateAverageTurnaroundTime(List<Process> processes) {
        int totalTurnaroundTime = 0;
        for (Process process : processes) {
            int turnaroundTime = process.getCompletionTime() - process.getArrivalTime();
            totalTurnaroundTime += turnaroundTime;
        }
        return (double) totalTurnaroundTime / processes.size();
    }
}

参考文献:郁红英;王磊;武磊;李春强. 计算机操作系统[M]. 第三版. 清华大学出版社, 2018年.

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
短作业优先调度算法(Shortest Job First, 简称SJF)是一种基于作业运行时间的调度算法,即优先调度运行时间最短的作业。该算法可以减少平均等待时间和平均周转时间,提高系统效率。 实验目的: 通过模拟短作业优先调度算法,了解其原理和应用,掌握算法实现方法。 实验要求: 1. 设计并实现短作业优先调度算法的模拟程序,模拟多个作业在系统中的运行过程。 2. 输入作业运行时间,模拟作业的提交和运行过程,输出每个作业的等待时间、周转时间和平均周转时间等统计信息。 3. 通过比较不同调度算法实验结果,分析短作业优先调度算法的优缺点。 实验步骤: 1. 设计作业控制块(Job Control Block, 简称JCB),包括作业ID、作业状态、作业优先级、作业运行时间、作业提交时间、作业开始运行时间、作业结束时间等属性。 2. 设计作业调度器,实现作业提交、作业调度和作业完成等操作。 3. 根据短作业优先调度算法的原理,实现作业排序和调度过程。按照作业运行时间的短到长排序,依次调度作业运行。 4. 模拟多个作业的提交和运行过程,记录每个作业的等待时间、周转时间等信息。 5. 输出统计信息,包括每个作业的等待时间、周转时间、平均周转时间等。 6. 分析实验结果,比较短作业优先调度算法和其他调度算法的优缺点,得出结论。 实验思考题: 1. 短作业优先调度算法适用于哪些场景?有哪些缺点? 2. 如何实现优先级调度算法?与短作业优先调度算法有何区别? 3. 如何解决作业优先级相同的情况? 4. 为什么多级反馈队列调度算法可以兼顾短作业和长作业? 5. 在实际操作系统中,如何实现作业调度?有哪些调度算法被广泛应用? 参考答案: 1. 短作业优先调度算法适用于作业运行时间相差较大的场景,可以减少平均等待时间和平均周转时间,提高系统效率。缺点是无法保证长作业得到及时执行,可能会出现长作业饥饿的情况。 2. 优先级调度算法可以根据作业的优先级进行调度,可以实现多种优先级调度策略。与短作业优先调度算法的区别在于,优先级调度算法是根据作业的优先级来排序和调度的。 3. 当作业优先级相同时,可以采用先来先服务(First Come First Served, 简称FCFS)或轮转调度(Round Robin, 简称RR)等策略来调度作业。 4. 多级反馈队列调度算法可以将作业分成多个队列,不同队列的调度策略不同。短作业可以在高优先级队列中得到及时调度,长作业可以在低优先级队列中得到充分的执行时间。因此,该算法可以兼顾短作业和长作业。 5. 在实际操作系统中,作业调度通常由内核来完成。常用的调度算法包括FCFS、SJF、优先级调度、RR、最短剩余时间优先调度(Shortest Remaining Time Next, 简称SRTN)等。不同的操作系统可能采用不同的调度算法,甚至可以根据不同场景采用不同的调度算法

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值