博客
关于我
模拟FCFS调度算法(先来先服务)没错,是篇好文章!
阅读量:546 次
发布时间:2019-03-08

本文共 5010 字,大约阅读时间需要 16 分钟。

FCFS调度算法及其实现分析

一、FCFS介绍

FCFS(First Come First Served,先来先服务)是一种简单的过程调度算法,主要应用于操作系统中的进程调度和资源分配。其核心思想是按照进程到达的先后顺序进行调度,当有进程需要访问资源时,系统会立即将其调入内存并开始执行,直到该进程完成或被暂停等待其他事件。

简单来说,FCFS调度算法就像名字所说的“先来先服务”,系统会按照进程到达的顺序依次处理每个进程。


二、代码分析与实现

1. 进程节点模拟

在本次模拟系统中,所有进程都以“节点形式”存在。每个节点包含以下属性:

  • 到达时间(Arrival Time):进程到达系统的时间戳
  • 服务时间(Service Time):进程在内存中占用资源的时间间隔
  • 完成时间(Finish Time):进程完成运行的绝对时间点
  • 周转时间(Turn Time):进程离开系统(从到达时间到完成时间的总时长)
  • 带权周转时间(Weighted Turn Time):周转时间与服务时间的比率(为衡量进程效率的重要指标)
  • 进程名称(Process Name):进程的唯一标识符

节点之间通过指针连接起来,形成一个链表结构。

2. 核心模拟类——SimulateFCFS

SimulateFCFS类是整个模拟系统的核心,负责处理以下主要任务:

a. 创建初始进程队列

系统模拟时,首先需要创建一个包含多个进程的队列。每个进程都需要注入到队列中,队列的结构就是我们上面提到的链表形式。

public void createQueue() {    Queue arr = null;    Queue temp = head;    Scanner scanner = new Scanner(System.in);    int n = scanner.nextInt();    for (int i = 1; i <= n; i++) {        System.out.printf("请输入第 %d 个进程的名称、到达时间和服务时间:", i);        arr = new Queue();        keyBordInput(arr, scanner);        calTime(arr); // 计算完成时间等属性        temp.next = arr;        temp = arr;    }    tail = arr;    System.out.println("模拟初始成功!");}

b. 输入进程属性

每个进程的属性(比如进程名称、到达时间、服务时间)需要通过键盘输入来配置。系统提供一个工厂方法来集中输入这些属性。

public void keyBordInput(Queue arr, Scanner scanner) {    arr.processName = scanner.next();    arr.arrTime = scanner.nextInt();    arr.serviceTime = scanner.nextInt();}

c. 计算进程时间属性

calTime方法用于根据全局时间变量 timer 来计算每个进程的完成时间等属性。这个方法确保每个进程的完成时间基于队列的实际运行情况。

public void calTime(Queue arr) {    if (this.timer < arr.arrTime) {        this.timer = arr.arrTime;    } else {        if (timer == 0) {            this.timer = arr.arrTime;        }    }    arr.finishTime = arr.serviceTime + this.timer;    arr.turnTime = arr.finishTime - arr.arrTime;    arr.weightTurnTime = (arr.turnTime * 1.0) / arr.serviceTime;    this.timer += arr.serviceTime;}

三、核心模拟逻辑

1. 进程到达与入队

当一个进程到达系统时,系统会将其添加到队列尾部。队列的首位进程(即队首节点)会立即获得资源并开始运行。

2. 进程调度与执行

系统采用先来先服务的调度算法,每次从队列头部取出一个进程进行调度。如果有多个进程同时到达,系统会按照到达时间顺序依次调度。


四、代码实现细节

1. 队列结构

队列采用链表结构,每个节点包含以下属性:

class Queue {    int arrTime; // 到达时间    int serviceTime; // 服务时间    int finishTime; // 完成时间    int turnTime; // 周转时间    double weightTurnTime; // 带权周转时间    String processName; // 进程名称    Queue next; // 下一个节点指针    public Queue(int arrTime, int serviceTime, String processName) {        this.arrTime = arrTime;        this.serviceTime = serviceTime;        this.processName = processName;    }    public Queue() {        // 默认构造一个空节点    }}

2. 模拟核心类

SimulateFCFS类负责管理整个模拟系统的运行。以下是其核心方法:

class SimulateFCFS {    private Queue head = new Queue(); // 队列头节点    private int timer = 0; // 全局时间变量    private Queue tail = head; // 队列尾节点    public void createQueue() {        int n = scanner.nextInt();        for (int i = 1; i <= n; i++) {            Queue arr = new Queue();            keyBordInput(arr, scanner);            calTime(arr); // 计算时间属性            if (head.next == null) {                head.next = arr;            }            tail = tail.next = arr;        }        System.out.println("初始化成功!");    }    public void assignProcess() {        Queue newProcess = new Queue();        keyBordInput(newProcess, scanner);        calTime(newProcess);        tail.next = newProcess;        tail = newProcess;    }    public void finishAllProcessTask() {        if (isEmpty()) {            return;        }        Queue cur = head.next;        System.out.println("进程名称 | 到达时间 | 服务时间 | 完成时间 | 周转时间 | 带权周转时间");        while (true) {            System.out.println(                String.format(                    "\t%s\t%d\t%d\t%d\t%d\t%f",                    cur.processName,                    cur.arrTime,                    cur.serviceTime,                    cur.finishTime,                    cur.turnTime,                    cur.weightTurnTime                )            );            if (cur.next == null) {                break;            }            cur = cur.next;        }    }    public boolean isEmpty() {        return head.next == null;    }}

3. 时间计算逻辑

calTime方法是时间计算的核心逻辑。它确保每个进程的完成时间和周转时间是基于实际运行情况计算的。

public void calTime(Queue arr) {    if (timer < arr.arrTime) {        timer = arr.arrTime;    } else {        if (timer == 0) {            timer = arr.arrTime;        }    }    arr.finishTime = arr.serviceTime + timer;    arr.turnTime = arr.finishTime - arr.arrTime;    arr.weightTurnTime = (arr.turnTime / arr.serviceTime) * 1.0;    timer += arr.serviceTime;}

五、系统操作说明

系统提供四种主要操作:

  • a:输入多个进程任务,初始化队列。
  • b:输入单个进程,添加到队列尾部。
  • d:完成所有进程的工作。
  • e:退出模拟系统。
  • 使用方法如下:

    while (flag) {    System.out.println("请输入指令:");    char at = scanner.next().charAt(0);    switch (at) {        case 'a':            simulateFCFS.createQueue();            break;        case 'b':            simulateFCFS.assignProcess();            break;        case 'd':            simulateFCFS.finishAllProcessTask();            return;        case 'e':            System.out.println("模拟结束!");            return;        default:            System.out.println("请输入正确指令!");            break;    }}

    通过以上分析,可以清晰地看到FCFS调度算法的实现原理及其在实际系统模拟中的应用。这套代码不仅能够模拟进程调度过程,还能输出各个进程的性能统计数据,为实际系统性能分析提供数据支持。

    转载地址:http://euyiz.baihongyu.com/

    你可能感兴趣的文章
    openjudge 1792 迷宫 解析报告
    查看>>
    Openlayers Draw的用法、属性、方法、事件介绍
    查看>>
    Openlayers layer 基础及重点内容讲解
    查看>>
    Openlayers map三要素(view,target,layers),及其他参数属性方法介绍
    查看>>
    Openlayers Map事件基础及重点内容讲解
    查看>>
    Openlayers Select的用法、属性、方法、事件介绍
    查看>>
    Openlayers Source基础及重点内容讲解
    查看>>
    Openlayers view三要素(zoom,center,projection)及其他参数属性方法介绍
    查看>>
    OpenLayers 入门使用
    查看>>
    Openlayers 入门教程(一):应该如何学习 Openlayers
    查看>>
    openlayers 入门教程(三):view 篇
    查看>>
    openlayers 入门教程(九):overlay 篇
    查看>>
    openlayers 入门教程(二):map 篇
    查看>>
    openlayers 入门教程(五):sources 篇
    查看>>
    openlayers 入门教程(八):Geoms 篇
    查看>>
    openlayers 入门教程(十三):动画
    查看>>
    openlayers 入门教程(十二):定位与轨迹
    查看>>
    openlayers 入门教程(十五):与 canvas、echart,turf 等交互
    查看>>
    openlayers 入门教程(十四):第三方插件
    查看>>
    openlayers 入门教程(四):layers 篇
    查看>>