操作系统课程设计之时间片轮转调度算法模拟(Java版本可视化)

1. 课程设计要求
本次课程设计的题目是,时间片轮转调度算法的模拟实现。要求在充分理解时间片轮转调度算法原理的基础上,编写一个可视化的算法模拟程序。
具体任务如下:
(1)根据需要,合理设计PCB结构,以适用于时间片轮转调度算法;
(2)设计模拟指令格式,并以文件形式存储,程序能够读取文件并自动生成指令序列。
(3)根据文件内容,建立模拟进程队列,并能采用时间片轮转调度算法对模拟进程进行调度。
任务要求:
(1)进程的个数,进程的内容(即进程的功能序列)来源于一个进程序列描述文件。
(2)需将调度过程输出到一个运行日志文件。
(3)开发平台及语言不限。
(4)要求设计一个Windows可视化应用程序。
2. 课程设计说明
模拟指令的格式:操作命令+操作时间
● C : 表示在CPU上计算
● I : 表示输入
● O : 表示输出
● W : 表示等待
● H : 表示进程结束
操作时间代表该操作命令要执行多长时间(时间片个数)。这里假设I/O设备的数量没有限制,I和O设备都只有一类。
I,O,W三条指令实际上是不占有CPU的,执行这三条指令就应该将进程放入对应的等待队列(输入等待队列,输出等待队列 ,其他等待队列)。

进程名称 进程信息
P1 C10 I20 C40 I30 C20 O30 H00
P2 I10 C50 O20 H00
P3 C10 I20 W20 C40 O10 H00

以上表格内容为进程具体时间片安排信息,存放在prc.txt文件中等待读取。

3. 课程设计UI界面

此处时间片默认为(500)单位为ms
需求分析:
本小程序需要实现的功能以下可见
打开文件 选择文件 读取文件 时间片设置 开始调度 暂停调度 以及最后的日志输出
4. 预备知识
(1)编程需要掌握:
Java基本语法;
此处我用软件eclipse进行Java编程;
Java的swing使用插件 WindowsBulider插件进行UI界面的设计;
Java列表的使用;
Java线程的分配;
插件的安装教程见插件安装教程
(2)时间片轮转调度算法掌握:
(借鉴别人的博客,后面附有连接)
在轮转RR法中,系统根据FCFS策略,将所有的就绪进程排成一个就绪队列,并可设置每隔一定时间间隔(如30 ms)即产生一次中断, 激活系统中的进程调度程序, 完成一次调度,将CPU分配给队首进程,令其执行。当该进程的时间片耗尽或运行完毕时,系统再次将CPU分配给新的队首进程(或新到达的紧迫进程)。由此,可保证就绪队列中的所有进程在一个确定的时间段内,都能够获得次 CPU执行。
5. 关键代码
所有程序包括三个类(个人设计三个,随自己,也可以一个)
PCB类(存放文件读取来的进程的信息)

public class PCB {private String pName;//进程名称private List pInstructions = new ArrayList<Instructions>();//进程中的指令列表private int CurrentInstruction;        //当前运行指令索引//后面自己添加其成员的get set方法}

Instructions类(动态的获取进程的信息机更新进程信息)

 private char IName;           //指令类型private double IRuntime;   //指令运行时间private double IRemainTime;  //指令剩余运行时间//后面自己添加get set 方法//再添加一个时间片控制方法 减时间片public void subIRemainTime(){this.setIRemainTime(this.getIRemainTime()-1);}

主类(关键部分,完成整个程序功能的实现,以及界面的展示)

//界面元素的定义private JButton bFIle, bStart, bStop;private JTextField tTime, tCur;private JTextArea tAll, tReady, tInput, tOutput, tWait;//队列文本域private File file;
//进程信息列表定义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;//Thread线程控制方法private long count = 0;//计数器

在主类中定义其他关键方法

文件的读写方法

private void readFile() {if (file != null) {try {BufferedReader in = new BufferedReader(new FileReader(file));String str;allQue.clear();PCB pcb = null;while ((str = in.readLine()) != null) {if (str.charAt(0) == 'P') {pcb = new PCB();pcb.setpName(str);} else {Instructions instructions = new Instructions();instructions.setIName(str.charAt(0));instructions.setIRuntime(parseDouble(str.substring(1)));instructions.setIRemainTime(instructions.getIRuntime());assert pcb != null;pcb.getpInstructions().add(instructions);if (instructions.getIName() == 'H') {//H代表当前进程结束,添加到就绪队列allQue.add(pcb);}}}} catch (IOException e) {System.out.println("文件读取错误!");}}}private void chooseFile() {//选择文件FileNameExtensionFilter filter = new         FileNameExtensionFilter("*.txt", "txt");JFileChooser jfc = new JFileChooser(".");//当前目录下jfc.setFileFilter(filter);jfc.setMultiSelectionEnabled(false);jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);int result = jfc.showSaveDialog(null);if (result == JFileChooser.APPROVE_OPTION) {file = jfc.getSelectedFile();}}

界面按钮事件

bFIle.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {chooseFile();readFile();saveLog("读取文件成功!\r\n________________________\r\n");showAll(allQue);}});//开始按钮事件
bStart.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (allQue.size()==0) {JOptionPane.showMessageDialog(null, "请重新选择文件!",JOptionPane.INFORMATION_MESSAGE);return;}if (boolTTime()) {initQue();startRun();}}});
bStop.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {bStart.setText("继续调度");blinker = null;}});

初始化队列

private void initQue() {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);}}}

进程队列运转更新方法

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) {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) {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) {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) {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));}}

日志的生成方法(日志的生成在程序目录下当然也可以自己随意该位置的)

public void startRun() {Runnable runnable = new Runnable() {public void run() {saveLog("------正在进行调度-------");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("");saveLog("调度已完成");} else {saveLog("调度已停止");}}};blinker = new Thread(runnable);blinker.start();}

其他子方法

 private void showAll(ArrayList<PCB> allQue) {tAll.setText("");for (PCB p : allQue) {tAll.setText(tAll.getText() + "\r\n" + p.getpName());}}private void showWait(ArrayList<PCB> waitQue) {tWait.setText("");for (PCB p : waitQue) {tWait.setText(tWait.getText() + "\r\n" + p.getpName());}}private void showOut(ArrayList<PCB> outQue) {tOutput.setText("");for (PCB p : outQue) {tOutput.setText(tOutput.getText() + "\r\n" + p.getpName());}}private void showIn(ArrayList<PCB> inQue) {tInput.setText("");for (PCB p : inQue) {tInput.setText(tInput.getText() + "\r\n" + p.getpName());}}private void showReady(ArrayList<PCB> que) {tReady.setText("");for (PCB p : que) {tReady.setText(tReady.getText() + "\r\n" + p.getpName());}}

最后在main方法中新建一个主类,即可运行得到程序。(结构如下)
6. 结果演示

  1. 提供帮助
    本程序的出处来自[此篇博客]感谢这个博主,真的很热心,但在其基础上进一步加以详细描述(适用于我一样的小白),应为当初我看到这篇博客的时候认为看到了救星,结过并不是想的那么详细。如果有一点java基础的同学,想必看到这篇文章后一定对你有所帮助,若没有基础,第一次碰java就别想了吧,就算拿到代码你也不一定跑的出来。
    附java环境配置可以在CSDN上面找到相关教程(关键 JDK的配置,一定要加到环境变量中,eclipse程序方可打开)。
    记住,每个人都不是一座孤岛,遇到困难先别放弃,先在网上找找,因为程序员最好的帮手,就应该有现如今发达的网络。

java时间片轮转调度(操作系统课程设计)相关推荐

  1. 操作系统课程设计——进程调度模拟程序(JAVA语言实现)

    本科期间的一些学习回忆记录(自己用) 一.课程设计的任务和要求 本次课程设计的题目是,时间片轮转调度算法的模拟实现.要求在充分理解时间片轮转调度算法原理的基础上,编写一个可视化的算法模拟程序.  具体 ...

  2. 操作系统分区分配java算法_合肥工业大学操作系统课程设计 动态分区分配存储管理java版.doc...

    合肥工业大学操作系统课程设计 动态分区分配存储管理java版.doc 1课程设计动态分区分配存储管理设计题目学号专业班级学生姓名号指导教师22010年12月合肥工业大学课程设计任务书设计题目动态分区分 ...

  3. java编写文件系统的方法_操作系统课程设计模拟文件系统Java

    [实例简介] 一个操作系统课程设计,使用java语言模拟磁盘文件系统实现,实现了FAT算法 [实例截图] [核心代码] e692cc3b-c785-40f6-babe-2f9d5383f034 └── ...

  4. 操作系统课程设计geekos project1-3

    概述 实验环境 GeekOS-0.3.0 Bochs和Vmware介绍 开发过程 编译运行 配置文件 前导知识 一.全局描述符表GDT(Global Descriptor Table) 二.段选择子( ...

  5. linux课程设计死锁避免,linux操作系统课程设计—车辆死锁.doc

    linux操作系统课程设计-车辆死锁.doc 键入文字"操作系统原理"课程设计BX090709吴沛儒操作系统原理课程设计报告姓名吴沛儒班级BX0907学号9指导老师胡静二〇一一年十 ...

  6. GeekOS操作系统课程设计 project1

    GeekOS操作系统课程设计 project1 项目设计1 一.项目设计目的 二.项目设计要求 三.步骤 1.修改project1/src/geekos/elf.c文件 1.1 在函数Parse_EL ...

  7. 操作系统课程设计pintos project1实验摘记

    前言: 本篇意在记录本学期结束的操作系统课程设计pintos project1实验报告和实现过程.整个实验参考了多篇文章也查阅了一些代码,其中部分内容或与其他文章相同,还请见谅.同时,也为了测试CSD ...

  8. 操作系统课程设计报告2021-2022——pintos

    操作系统课程设计报告 2021-2022 目录 操作系统课程设计报告 2021-2022 第一章 实验项目介绍 环境配置 ( 一 ). Ubuntu 服务器搭建 图形界面搭建 ( 二 ). Pinto ...

  9. 操作系统课程设计报告总结(下)

    操作系统课程设计报告总结(下) 实验六 银行家算法的模拟与实现 实验目的 总体设计 背景知识 基本原理 模块介绍 详细设计 关键代码及分析 实验结果与分析 小结与心得体会 银行家算法源码 实验七 磁盘 ...

最新文章

  1. 单片机编程好学吗?单片机初学者怎样看懂代码?
  2. cuda 安装_win10+VS 2017 安装 CUDA(Visual Studio Integration失败)
  3. CodeSmith(9)访问数据库多个表
  4. 数学之美笔记(二十)
  5. 【整理】SAP PM工厂维护模块初识
  6. 移动端 | table 布局
  7. apache2怎么知道从哪个默认文件夹下去查找网页
  8. 专为小机械迷而造,培养STEM思维,千万别错过!物理机械力学知识边玩边学,5岁以上请入手...
  9. python虚拟人脸生成_GitHub - 597111463/seeprettyface-generator-yellow: 这是一个用StyleGAN训练出的黄种人人脸生成器...
  10. 32位单精度浮点乘法器的FPGA实现
  11. spark 监控--WebUi、Metrics System(转载)
  12. 2009年IT就业“危”中寻“机”
  13. bootstrap - 弹出层
  14. Oracle中包的创建
  15. 一道组合数学题-马拦过河卒,很精彩
  16. 读取Flash w25x64未响应 导致卡死的问题
  17. Linux下设置桌面快捷方式(应用图标快速启动)
  18. PDF文件JAVA去水印源码,java实现pdf文件加水印
  19. 计算机相关的专刊,计算机 | 1区SCI期刊专刊信息1条
  20. 你和那位明星同月同日出生(呵呵。。你就别想同年了啊)

热门文章

  1. Java 求解平衡二叉树
  2. 上海信职冷鳞网络工作室
  3. 浏览器HTTPS访问问题
  4. C语言浮点数的发送和接收
  5. 送5本新出版的算法书
  6. flask 数据库操作入门教程(一把梭)
  7. 采集简历、考勤数据,社保申报等人力资源领域自动化如何实现?
  8. Windows配置pip国内镜像源
  9. java数组的长度不确定怎么办_java中申请不定长度数组ArrayList的方法
  10. 冯诺依曼机器的并发—带着脚镣跳舞