操作系统——FCFS算法(Java实现)

Java操作系统进程调度算法------先来先服务(FCFS)算法

一、算法思想

先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。采用FCFS算法,每次从后备队列中选择一个或多个最先进入该队列的作业,将他们调入内存,为他们分配资源,创建进程,然后放入就绪队列。在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。

二、算法分析

假设现在有五个进程先后到达系统进行调度

进程号进程名到达时间服务时间(执行时间)
1001p19:4020
1004p410:1010
1005p510:0530
1002p29:5515
1003p39:4525

在先来先服务算法中,由于在0时刻系统中只有作业p1,因比系统将优先为作业p1进行调度。作业p1在完成的过程中作业p2、p3、p4、p5先后都到达了系统中。也就是说在作业p1调度完成后系统中会有p2、p3、p4、p5四个作业等待调度。根据先来先服务的思想,
系统将依次按p3、p2、p5、p4的顺序为接下来的四个作业进行调度。

周转时同 = 完成时间 - 到达时间

p1 = 10:00 - 9:40 = 20; p2 = 10:40 - 9:55 = 45; p3 = 10:25 - 9:45 = 40; p4 = 11:20 - 10:10 = 70; p5 = 11:10 - 10:05 = 65;

带权周转时间=周转时间/运行时间

p1 = 20 / 20 = 1; p2 = 45 / 15 = 3; p3 = 40 / 25 = 1.6; p4 = 70 / 10 = 7; p5 = 65 / 30 = 2.17
等待时间=周转时间-运行时间(分钟)

p1 = 20 - 20 = 0; p2 = 45 - 15 = 30; p3 = 40 - 25 = 15; p4 = 70 - 10 = 60; p5 = 65 - 30 = 35

平均周转时间Q=(20 + 45 + 40 + 70 + 65) / 5 = 48
平均带权周转时间=(1 + 3 + 1.6 + 7 + 2.17 ) = 2.96
平均等待时间=(0 +30 +15 + 60 +35 ) / 5 = 28

三、数据结构

1.作业数据类

class ProcessData{
    //进程号
    public int id;
    //进程名字
    public String name;
    //到达时间
    public LocalTime arriveTime;
    //执行时间
    public double serviceTime;
    //开始时间
    public LocalTime startTime;
    //完成时间
    public LocalTime finishTime;
    //周转时间
    public double wholeTime;
    //带权周转时间
    public double weightWholeTime;

    public ProcessData(int id, String name, String arriveTime, double serviceTime) {
        this.id = id;
        this.name = name;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H:m");
        this.arriveTime = LocalTime.parse(arriveTime,formatter);
        this.serviceTime = serviceTime;
    }

    @Override
    public String toString() {
        return id + "\t" +
                name + "\t" +
                arriveTime + "\t" +
                serviceTime + "\t" +
                startTime + "\t" +
                finishTime + "\t" +
                wholeTime + "\t" +
                weightWholeTime;
    }
}

2.作业调度(算法实现部分)

package cn.homyit;

import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;

/**
 * @param:
 * @description:
 * @author: Answer
 * @create:2024/3/7 18:31
 **/
public class FCFS {
    //平均周转时间
    public static double avgWholeTime;
    //平均带权周转时间
    public static double avgWeightWholeTime;

    public static void main(String[] args) {
        boolean answer = true;
        Scanner myScanner = new Scanner(System.in);
        while (answer){
            System.out.print("请输入将要进行的操作:(1:开始进程;-1:结束进程):");
            int condition = myScanner.nextInt();
            if (condition == 1){
                System.out.print("请输入进程个数:");
                int num = myScanner.nextInt();
                ProcessData[] processData = new ProcessData[num];
//                System.out.println( "id\t名字\t到达时间\t执行时间(分钟)" );
                System.out.println( "id    \t  名字    \t 到达时间\t   执行时间(分钟)" );
                for( int i = 0; i < num; i++ ) {
                    processData[i] = new ProcessData
                            (myScanner.nextInt(),
                            myScanner.next(),
                            myScanner.next(),
                            myScanner.nextDouble());
                }
                fcfs(processData);
            } else if (condition == -1) {
                answer = false;
                return;
            }else {
                System.out.println("请输入正确操作!");
            }
        }
    }


    //先来先服务算法实现
    private static void fcfs(ProcessData[] processData){
        avgWholeTime = 0;//平均周转时间
        avgWeightWholeTime = 0;//平均带权周转时间

        //初始化完成的时间,周转时间,带权周转时间的初始化
        for (ProcessData processDatum : processData) {
            processDatum.finishTime = LocalTime.parse("00:00");//设置初始时间为0:00
            processDatum.wholeTime = 0;//设置平均周转时间为0
            processDatum.weightWholeTime = 0;//设置平均带权周转时间为0
        }

        //1.按照到达时间进行排序
        int n = processData.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (!timeComparison(processData[j].arriveTime,processData[j + 1].arriveTime)) {
                    // 交换元素
                    ProcessData temp = processData[j];
                    processData[j] = processData[j + 1];
                    processData[j + 1] = temp;
                }
            }
        }
        //2.第一个作业的到达时间应为第一个作业的开始时间
        processData[0].startTime = processData[0].arriveTime;
        for (int i = 0; i < processData.length ; i++) {
            //作业的完成时间为上一个作业的完成时间或者开时时间 + 当前作业的服务时间
            processData[i].finishTime = processData[i].startTime.plusMinutes((long) processData[i].serviceTime);
            //下一个任务的开始时间 = 当前任务的完成时间
            if(i!= processData.length - 1) {
                processData[i + 1].startTime = processData[i].finishTime;
            }
            //周转时间 = 完成时间 - 到达时间
            processData[i].wholeTime = ChronoUnit.MINUTES.between(processData[i].arriveTime,processData[i].finishTime);
            //带权周转时间 = 周转时间 / 系统提供的服务时间
            processData[i].weightWholeTime = processData[i].wholeTime / processData[i].serviceTime;
        }
        System.out.println("模拟进程fcfs调度过程输出结果:");

        print(processData);
    }


    //打印
    private static void print(ProcessData[] processData) {
        System.out.println("ID号\t" + "名字\t" + "到达时间\t" + "执行时间(分钟)\t" + "开始时间\t" + "完成时间\t" + "周转时间(分钟)\t" + "带权周转时间(系数)\t");
        for (ProcessData processData1 : processData){
            System.out.println(processData1);
            avgWholeTime += processData1.wholeTime;
            avgWeightWholeTime += processData1.weightWholeTime;
        }
        avgWholeTime = avgWholeTime / processData.length;
        avgWeightWholeTime = avgWeightWholeTime / processData.length;
        System.out.println("系统平均周转时间为:" + avgWholeTime);
        System.out.println("系统带权平均周转时间为:" + avgWeightWholeTime);
    }

    private static boolean timeComparison(LocalTime time1, LocalTime time2){
        return time1.isBefore(time2);
    }
}

3.运行结果在这里插入图片描述

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,进程调度算法操作系统中非常重要的一部分。常见的进程调度算法先来先服务FCFS)、短作业优先(SJF)、高响应比优先(HRRN)、时间片轮转(RR)等。下面是这些算法的 Python 实现: 1. 先来先服务FCFS): ```python def FCFS(processes): waiting_time = 0 turn_around_time = 0 completion_time = 0 for process in processes: completion_time += process['burst_time'] turn_around_time += completion_time - process['arrival_time'] waiting_time += turn_around_time - process['burst_time'] return waiting_time / len(processes), turn_around_time / len(processes) ``` 2. 短作业优先(SJF): ```python def SJF(processes): processes = sorted(processes, key=lambda x: x['burst_time']) waiting_time = 0 turn_around_time = 0 completion_time = 0 for process in processes: completion_time += process['burst_time'] turn_around_time += completion_time - process['arrival_time'] waiting_time += turn_around_time - process['burst_time'] return waiting_time / len(processes), turn_around_time / len(processes) ``` 3. 高响应比优先(HRRN): ```python def HRRN(processes): waiting_time = 0 turn_around_time = 0 completion_time = 0 for i, process in enumerate(processes): if i == 0: completion_time = process['burst_time'] else: response_ratio_list = [] for j in range(i): response_ratio = (completion_time - processes[j]['arrival_time'] + processes[j]['burst_time']) / processes[j]['burst_time'] response_ratio_list.append(response_ratio) max_response_ratio_index = response_ratio_list.index(max(response_ratio_list)) selected_process = processes.pop(max_response_ratio_index) completion_time += selected_process['burst_time'] turn_around_time += completion_time - selected_process['arrival_time'] waiting_time += turn_around_time - selected_process['burst_time'] return waiting_time / len(processes), turn_around_time / len(processes) ``` 4. 时间片轮转(RR): ```python def RR(processes, time_slice): waiting_time = 0 turn_around_time = 0 completion_time = 0 while processes: for i in range(len(processes)): if processes[i]['burst_time'] > time_slice: completion_time += time_slice processes[i]['burst_time'] -= time_slice else: completion_time += processes[i]['burst_time'] turn_around_time += completion_time - processes[i]['arrival_time'] waiting_time += turn_around_time - processes[i]['burst_time'] processes.pop(i) break return waiting_time / len(processes), turn_around_time / len(processes) ``` 这里的 `processes` 是一个列表,其中每个元素是一个字典,表示一个进程的信息,如下所示: ```python processes = [ {'name': 'P1', 'arrival_time': 0, 'burst_time': 8}, {'name': 'P2', 'arrival_time': 1, 'burst_time': 4}, {'name': 'P3', 'arrival_time': 2, 'burst_time': 9}, ... ] ``` 在这个列表中,每个进程有一个名称、到达时间和执行时间。你可以根据自己的需要修改这些信息,来测试这些进程调度算法实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值