记录——时间片轮转调度算法模拟程序,用Java实现[亲测有效]

记录——时间片轮转调度算法模拟程序,用Java实现[亲测有效]1、合理设计PCB结构,设计模拟指令格式,并以文件形式存储,程序能够读取文件并自动生成指令序列。2、根据文件内容,建立模拟进程队列,并能采用时间片轮转调度算法对模拟进程进行调度。

大家好,欢迎来到IT知识分享网。

前言

      现代计算机系统中,进程是资源分配和独立运行的基本单位,是操作系统的核心概念。因而,进程就成为理解操作系统如何实现系统管理的最基本,也是最重要的概念。进程调度是进程管理过程的主要组成部分, 对于不同的系统和系统目标,通常采用不同的调度算法。采用算法时,则要考虑多方面因素,以便达到最佳效果。在分时系统中,最简单也是较常见的是基于时间片的轮转调度算法,因此采用时间片轮转调度算法来实现模拟进程调度任务的执行过程。

 

 

一、目标及分析

目标:

1、合理设计PCB结构,设计模拟指令格式,并以文件形式存储,程序能够读取文件并自动生成指令序列。

2、根据文件内容,建立模拟进程队列,并能采用时间片轮转调度算法对模拟进程进行调度。

分析:

1、首先编写一个进程序列描述文件:包括进程的个数,进程的内容(即进程的功能序列);

2、程序应具有选择、读取、解析进程序列描述文件功能,根据解析的内容生成指令序列;

3、根据时间片轮转算法,应具有设置时间片大小功能;

4、开始调度按钮,进行模拟调度功能,界面显示调度过程;

5、停止调度功能按钮,停止模拟调度功能,整个系统中的进程调度程序都被停止,界面也应该有相应的显示;

6、将调度过程记录为文档。

二、进程序列描述文件

根据分析,进行描述文件设计

模拟指令的格式:操作命令+操作时间

● C : 表示在CPU上计算

● I : 表示输入

● O : 表示输出

● W : 表示等待

● H : 表示进程结束

操作时间代表该操作命令要执行多长时间(时间片个数)。这里假设I/O设备的数量没有限制,I和O设备都只有一类。

I,O,W三条指令实际上是不占有CPU的,执行这三条指令就应该将进程放入对应的等待队列(输入等待队列,输出等待队列 ,其他等待队列)。

例如,有一虚拟程序文件prc.txt描述如下,其中,指令后面的数值代表该指令需要执行的时间片个数,如C10,代表需要计算10个时间片:

P1

C10

I20

C40

I30

C20

O30

H00

P2

I10

C50

O20

H00

P3

C10

I20

W20

C40

O10

H00

 

三、界面设计

根据分析,设计界面

界面设计

 

四、功能实现

根据分析,程序可以分为6个功能:选择文件功能、读取分析文件功能、设置时间片大小、开始调度功能、记录功能、停止调度功能。

这里主要讲怎样实现开始、停止调度功能。
 

关于时间片轮转调度

      在轮转RR法中,系统根据FCFS策略,将所有的就绪进程排成一个就绪队列,并可设置每隔一定时间间隔(如30 ms)即产生一次中断, 激活系统中的进程调度程序, 完成一次调度,将CPU分配给队首进程,令其执行。当该进程的时间片耗尽或运行完毕时,系统再次将CPU分配给新的队首进程(或新到达的紧迫进程)。由此,可保证就绪队列中的所有进程在一个确定的时间段内,都能够获得次 CPU执行。

     其算法流程图如下:

时间片轮转算法流程图

按时间片轮转调度算法流程,功能实现思路如下:

①根据进程首指令的类别判断进程归属队列。

②执行处理机调度时,开始选择队首的第一个进程运行;每执行一次之后,该指令的剩余运行时间减一,输出当前运行进程的名字。

③若该进程的剩余运行时间为零,则说明该指令执行完成,将该指令从该进程中移除,如果下一条指令为‘H’则说明该进程结束,从就绪队列中移除;否则,下一条指令再次从①步骤开始。

④如果不为零,则将其移至队尾,从①步骤再次开始。

⑤若就绪队列不为空,则重复以上步骤,知道所有进程运行完为止

程序实现

前提:已完成文件解析,把所有的PCB存入allQue队列。

PCB类:

   private String pName;//进程名称
    private List pInstructions = new ArrayList<Instructions>();//进程中的指令列表
    private int CurrentInstruction;        //当前运行指令索引

Instructions类:

 private char IName;           //指令类型
    private double IRuntime;   //指令运行时间
    private double IRemainTime;  //指令剩余运行时间

 

界面元素:

  private JButton bFIle, bStart, bStop;//三个按钮
    private JTextField tTime, tCur;
    private JTextArea tAll, tReady, tInput, tOutput, tWait;//队列文本域显示
    private File file;
    private JLabel lInfo;
    private ArrayList<PCB> allQue = new ArrayList<PCB>();
    private ArrayList<PCB> readyQue = new ArrayList<PCB>();
    private ArrayList<PCB> inQue = new ArrayList<PCB>();
    private ArrayList<PCB> outQue = new ArrayList<PCB>();
    private ArrayList<PCB> waitQue = new ArrayList<PCB>();
    private volatile Thread blinker;
    private long count = 0;

开始,停止,继续按钮事件:

   bStart.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (allQue.size()==0) {
                    JOptionPane.showMessageDialog(null, "请重新选择文件!", "提示", JOptionPane.INFORMATION_MESSAGE);
                    return;
                }
                if (boolTTime()) {
                    initQue();
                    startRun();

                }
            }

        });
        bStop.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                bStart.setText("继续调度");
                blinker = null;
            }
        });
    }

 

初始化各个队列列表:

 private void initQue() {
        //把就绪进程排成一个就绪队列,即readyQue
        //I,O,W三条指令实际上是不占有CPU的,执行这三条指令就应该将进程放入对应的等待队列(输入等待队列,输出等待队列 ,其他等待队列)。
        //先清空队列
        readyQue.clear();
        inQue.clear();
        outQue.clear();
        waitQue.clear();
        //分配排序队列
        for (PCB p : allQue
                ) {
            if (p.getpInstructions().get(0).getIName() == 'C') {
                readyQue.add(p);
            } else if (p.getpInstructions().get(0).getIName() == 'I') {
                inQue.add(p);
            } else if (p.getpInstructions().get(0).getIName() == 'O') {
                outQue.add(p);
            } else if (p.getpInstructions().get(0).getIName() == 'W') {
                waitQue.add(p);
            }
        }
    }

开始调度:

 public void startRun() {
        Runnable runnable = new Runnable() {
            public void run() {
                saveLog("------正在进行调度-------");
                lInfo.setText("------正在进行调度-------");
                while (allQue.size() > 0 && blinker != null) {
                    try {
                        runReady();//就绪队列
                        runIn();//输入队列
                        runOut();//输出队列
                        runWait();//等待队列
                        showAll(allQue);
                        saveLog("就绪队列:\t" + tAll.getText() + "\r\n");
                        showReady(readyQue);
                        saveLog("后备就绪队列:\t" + tReady.getText() + "\r\n");
                        showIn(inQue);
                        saveLog("输入队列:\t" + tInput.getText() + "\r\n");
                        showOut(outQue);
                        saveLog("输出队列:\t" + tOutput.getText() + "\r\n");
                        showWait(waitQue);
                        saveLog("等待队列:\t" + tWait.getText() + "\r\n");

                        saveLog("_______________________________");
                        count++;
                        System.out.println(count);
                        sleep(Long.parseLong(tTime.getText()));

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (allQue.size() == 0) {
                    bStart.setText("开始调度");
                    tCur.setText("");
                    lInfo.setText("调度已完成(*^_^*)");
                    saveLog("调度已完成");
                } else {
                    lInfo.setText("调度已停止/(ㄒoㄒ)/~~");
                    saveLog("调度已停止");
                }
            }


        };
        blinker = new Thread(runnable);
        blinker.start();

    }

执行队列:

    private void runReady() {
        //就绪队列执行
        if (readyQue.size() > 0) {
            readyQue.get(0).getpInstructions().get(0).subIRemainTime();//调度首队列一次
            tCur.setText(readyQue.get(0).getpName());
            if (readyQue.get(0).getpInstructions().get(0).getIRemainTime() == 0) {
                //如果剩余时间为0,则说明运行完成
                //把该指令移除,根据下一个指令判断队列
                readyQue.get(0).getpInstructions().remove(0);
                if (readyQue.get(0).getpInstructions().get(0).getIName() == 'C') {
                    readyQue.add(readyQue.get(0));//添加到ready末尾
                } else if (readyQue.get(0).getpInstructions().get(0).getIName() == 'I') {
                    inQue.add(readyQue.get(0));//添加到in末尾
                } else if (readyQue.get(0).getpInstructions().get(0).getIName() == 'O') {
                    outQue.add(readyQue.get(0));//添加到out末尾
                } else if (readyQue.get(0).getpInstructions().get(0).getIName() == 'W') {
                    waitQue.add(readyQue.get(0));//添加到wait末尾
                } else if (readyQue.get(0).getpInstructions().get(0).getIName() == 'H') {
                    //说明该进程完成
                    allQue.remove(readyQue.get(0));
                }
                readyQue.remove(readyQue.get(0));
            } else {
                readyQue.add(readyQue.get(0));//移动到末尾
                readyQue.remove(readyQue.get(0));
            }
        }
    private void runIn() {
        if (inQue.size() > 0) {
            inQue.get(0).getpInstructions().get(0).subIRemainTime();//调度首队列一次
            if (inQue.get(0).getpInstructions().get(0).getIRemainTime() == 0) {
                //如果剩余时间为0,则说明运行完成
                //把该指令移除,根据下一个指令判断队列
                inQue.get(0).getpInstructions().remove(0);
                if (inQue.get(0).getpInstructions().get(0).getIName() == 'C') {
                    readyQue.add(inQue.get(0));//添加到ready末尾
                } else if (inQue.get(0).getpInstructions().get(0).getIName() == 'I') {
                    inQue.add(inQue.get(0));//添加到in末尾
                } else if (inQue.get(0).getpInstructions().get(0).getIName() == 'O') {
                    outQue.add(inQue.get(0));//添加到out末尾
                } else if (inQue.get(0).getpInstructions().get(0).getIName() == 'W') {
                    waitQue.add(inQue.get(0));//添加到wait末尾
                } else if (inQue.get(0).getpInstructions().get(0).getIName() == 'H') {
                    //说明该进程完成
                    allQue.remove(inQue.get(0));
                }
                inQue.remove(inQue.get(0));
            } else {
                inQue.add(inQue.get(0));//移动到末尾
                inQue.remove(inQue.get(0));
            }
        }
    }

    private void runOut() {
        if (outQue.size() > 0) {
            outQue.get(0).getpInstructions().get(0).subIRemainTime();//调度首队列一次
            if (outQue.get(0).getpInstructions().get(0).getIRemainTime() == 0) {
                //如果剩余时间为0,则说明运行完成
                //把该指令移除,根据下一个指令判断队列
                outQue.get(0).getpInstructions().remove(0);
                if (outQue.get(0).getpInstructions().get(0).getIName() == 'C') {
                    readyQue.add(outQue.get(0));//添加到ready末尾
                } else if (outQue.get(0).getpInstructions().get(0).getIName() == 'I') {
                    inQue.add(outQue.get(0));//添加到in末尾
                } else if (outQue.get(0).getpInstructions().get(0).getIName() == 'O') {
                    outQue.add(outQue.get(0));//添加到out末尾
                } else if (outQue.get(0).getpInstructions().get(0).getIName() == 'W') {
                    waitQue.add(outQue.get(0));//添加到wait末尾
                } else if (outQue.get(0).getpInstructions().get(0).getIName() == 'H') {
                    //说明该进程完成
                    if (allQue.size() > 0) {
                        allQue.remove(outQue.get(0));
                    }
                }
                outQue.remove(outQue.get(0));
            } else {
                outQue.add(outQue.get(0));//移动到末尾
                outQue.remove(outQue.get(0));
            }
        }
    }

    private void runWait() {
        if (waitQue.size() > 0) {
            waitQue.get(0).getpInstructions().get(0).subIRemainTime();//调度首队列一次
            if (waitQue.get(0).getpInstructions().get(0).getIRemainTime() == 0) {
                //如果剩余时间为0,则说明运行完成
                //把该指令移除,根据下一个指令判断队列
                waitQue.get(0).getpInstructions().remove(0);
                if (waitQue.get(0).getpInstructions().get(0).getIName() == 'C') {
                    readyQue.add(waitQue.get(0));//添加到ready末尾
                } else if (waitQue.get(0).getpInstructions().get(0).getIName() == 'I') {
                    inQue.add(waitQue.get(0));//添加到in末尾
                } else if (waitQue.get(0).getpInstructions().get(0).getIName() == 'O') {
                    outQue.add(waitQue.get(0));//添加到out末尾
                } else if (waitQue.get(0).getpInstructions().get(0).getIName() == 'W') {
                    waitQue.add(waitQue.get(0));//添加到wait末尾
                } else if (waitQue.get(0).getpInstructions().get(0).getIName() == 'H') {
                    //说明该进程完成
                    allQue.remove(waitQue.get(0));
                }
                waitQue.remove(waitQue.get(0));
            } else {
                waitQue.add(waitQue.get(0));//移动到末尾
                waitQue.remove(waitQue.get(0));
            }
        }
    }

五、程序运行

选择文件

选择文件

文件解析

解析文本

开始调度

开始调度

停止调度

停止调度

调度完成

调度完成

记录日志

调度完成

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/25854.html

(0)
上一篇 2023-07-05 11:00
下一篇 2023-07-08 11:00

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信