进程控制模块操作系统进程控制课程设计.doc
操作系统原理课 程 设 计 报 告 书题 目: 进程控制模块 学 号: 学生姓名: 专 业:计算机科学与技术卓越班指导教师: 2014年 12月 26日目 录1. 系统功能12. 系统设计22.1. 总体设计22.2. 详细设计22.2.1. 函数22.2.2. 数据结构32.2.3. 算法43. 系统实现53.1. 开发工具及语言53.2. 实现步骤53.3. 代码54. 系统测试与分析215. 总结251. 系统功能1、 实现进程调度算法选择,有先来先服务调度算法和优先级调度算法;2、 实现进程的创建;3、 实现进程的终止;4、 实现进程的阻塞;5、 实现进程的唤醒;6、 实现手动调度进程和进程自动执行两种模式; 执行 就绪 阻塞创建 许可 时间片用完I/O完成进程调度 I/O请求终止2. 系统设计2.1. 总体设计定义3个类,JieMian类、Process类、List类。1 JieMian类中布局程序界面,调用进程的创建、执行、终止、阻塞、唤醒等函数。2 Process类模拟进程,有3个变量,进程的名字 name、进程的时间片time、进程的优先级priority,还有对这3个变量赋值和得到变量的值得get函数、set函数。3 List类有两个变量,LinkedList<Process> readyList,就绪队列;LinkedList<Process> blockList,阻塞队列。2.2. 详细设计2.2.1. 函数包括函数声明(返回值、函数名、形参)和功能描述。1 JieMian():调用initframe()函数,初始化程序界面2 void initframe():初始化程序界面3 void actionPerformed(ActionEvent e):事件监听函数,属于库函数,重写该函数,实现所有按钮的事件的监听。4 void selectModel():选择手动或自动模式;5 void selectAlgorithm():选择调度算法的函数;6 void paiXu():当"先来先服务算法"转到“优先级算法”,对就绪队列的进程按优先级降序排序;7 void autoModel():进入自动模式,刷新按钮,启动线程;8 void run():线程类的线程函数,实现自动执行就绪队列中的进程,将时间片用完的进程再放回到就绪队列。9 void manualModel():进入手动模式的函数,刷新按钮。10 void createProcess():创建进程,当创建进程的条件不满足时,提示错误,成功创建进程后,将进程按照先来先服务算法或优先级算法将进程添加到就绪队列,然后刷新就绪队列的表格。11 paiXu(Process process):根据进程优先级算法,给就绪队列的进程排序,如果优先级相同,按先来先服务的方式排序;12 void runProcess ():手动模式下,执行进程的函数,将就绪队列的第一进程取出执行,并显示正在被执行的进程。13 void readyProcess():手动模式下,让正在执行的进程结束执行,再放回到就绪队列。14 void blockProcess():阻塞进程,将正在执行的进程阻塞,进程被阻塞后放到阻塞队列,然后刷新阻塞队列的表格。15 void wakeUpProcess():唤醒阻塞队列里的第一个阻塞的进程,将唤醒的进程按照先来先服务的算法或者优先级算法放到就绪队列中,并刷新就绪队列的表格。16 void shutDownProcess():终止进程,将正在执行的进程终止。17 void refresh_ReadyList():刷新就绪队列表格,把就绪队列里的就绪进程显示在就绪队列的表格中;18 void refresh_BlockList():刷新阻塞队列表格,把阻塞队列的阻塞进程显示在阻塞队列的表格中;19 void main(String arg):主函数,库函数,JieMian jm = new JieMian();实例化一个JieMian类的对象。2.2.2. 数据结构包括数据结构的定义。1 PCB的数据结构的定义:/进程类public class Process public String name;/进程名 public int time;/时间 public int priority;/进程优先级 public int num;/轮转次数public String getName() return name;public void setName(String name) this.name = name;public int getTime() return time;public void setTime(int time) this.time = time;public int getPriority() return priority;public void setPriority(int priority) this.priority = priority;public int getNum() return num;public void setNum(int num) this.num = num; 2 就绪队列和阻塞队列的数据结构的定义 public class List static LinkedList<Process> readyList = new LinkedList<Process>();/就绪队列static LinkedList<Process> blockList = new LinkedList<Process>();/阻塞队列2.2.3. 算法采用自然语言、流程图、N-S图、伪代码任一种描述。步骤1、选择模式,否则不能开始程序;步骤2、选择调度算法,否则不能创建进程;事件1、创建进程;(1)输入进程名字,名字要唯一,否则不能创建进程;选择进程的时间片,默认时间片为1;选择进程优先级,默认优先级为1;(2)判断就绪队列是否为空,若不为空则不能创建进程;(3)使用正则表达式验证进程名是否合法,否则不能创建进程;(4)、创建进程成功,将进程插入就绪队列,并在就绪队列表格中显示。事件2、执行进程;(1)判断就绪队列是否为空,即是否有可执行的进程;(2)、从就绪队列取出一个进程,赋值给runningProcess变量。事件3、阻塞进程;(1)判断是否有正在执行的进程;(2)、判断阻塞队列是否已满;(3) 、满足阻塞条件,将正在执行的进程放入阻塞队列; 事件4、唤醒进程;(1)判断是否有可唤醒的进程;(2)判断就绪队列是否已满;(3)按照已选择的调度算法,将被唤醒进程放入就绪队列,并刷新就绪队列表格,将进程移出阻塞队列。事件5、终止进程;判断是否有正在执行的进程,结束进程,令runningProcess=null;3. 系统实现3.1. 开发工具及语言开发工具:myeclipse语言:java3.2. 实现步骤步骤一:创建界面,初始化界面;步骤二:创建PCB,初始化PCB;步骤三:创建链表,初始化链表;3.3. 代码import java.awt.Color;import java.awt.Container;import java.awt.Font;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.FocusAdapter;import java.awt.event.FocusEvent;import java.awt.event.FocusListener;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.JTextArea;import javax.swing.ListSelectionModel; public class JieMian extends Thread implements ActionListener public JFrame frame = new JFrame();public Container cont = frame.getContentPane();public JPanel top_pan=new JPanel();public JPanel bottom_pan = new JPanel();/放ready_pan、ready_panpublic JPanel ready_pan=new JPanel(new GridLayout(1,0);/放就绪队列表格的panelpublic JPanel block_pan=new JPanel(new GridLayout(1,0);/放阻塞队列表格的panelpublic JLabel top_lab = new JLabel();public JLabel suanF_lab = new JLabel();/显示采用的算法public JLabel top_lab2 = new JLabel();public JButton confirm_bn = new JButton();public JButton ready_bn = new JButton();/就绪按钮public static JButton shutdown_bn = new JButton();/终止按钮public static JButton runn_bn = new JButton();/执行按钮public JButton block_bn = new JButton();/阻塞按钮public JButton wakeUp_bn = new JButton();/就绪按钮public JTextArea create_tx = new JTextArea();/创建进程的文本框public JButton create_bn = new JButton();/创建进程的按钮public static JComboBox set_auto_manual=new JComboBox();/下拉框,选择模式public JLabel auto_manual_lab = new JLabel();/标签public JComboBox suanFa=new JComboBox();/下拉框,选择调度算法public JButton suanFa_bn = new JButton();public JComboBox sdept_com=new JComboBox();/下拉框,选择进程时间片public JLabel time_lab = new JLabel();public JComboBox priority=new JComboBox();/下拉框,选择进程优先级public JLabel priority_lab = new JLabel();/优先级标签public JComboBox num=new JComboBox();/下拉框,选择进程轮转次数public JLabel num_lab = new JLabel();/轮转次数标签public JScrollPane scrollPane;/滚动条public JTable table; /表格public String columnName = "就绪队列","优先级"public Object data = new Object122;public ListSelectionModel cellSelectionModel;/就绪队列的public ListSelectionModel cellSelectionModel2;/阻塞队列的public JScrollPane scrollPane2;/滚动条public JTable table2; /表格public String columnName2 = "阻塞队列"public Object data2 = new Object121;/用于判断按钮是否需要刷新的变量int model1 = 0;/记录当前模式的前一个模式,0:初始值;1:自动模式;2:手动模式int model2 = 0;/记录当前模int algorithm = 0;/记录选取的算法模式;0:初始值;1:先来先服务;2:优先级算法boolean flag = false;/记录就绪队列是否为空public Process runningProcess = null;/记录正在执行的进程public boolean threadFlag = false;/记录线程是否在执行public boolean runStart = false;/记录线程的run()函数是否开始了public JieMian()this.initframe();Overridepublic void actionPerformed(ActionEvent e) / TODO Auto-generated method stubJButton bn=(JButton)e.getSource();if(bn = confirm_bn)/选择手动模式或自动模式this.selectModel();else if(bn = suanFa_bn)/选择算法this.selectAlgorithm();else if(bn=create_bn)/创建进程this.createProcess();else if(bn=block_bn)/阻塞进程this.blockProcess();else if(bn = wakeUp_bn)/唤醒进程this.wakeUpProcess();else if(bn = shutdown_bn)/终止进程this.shutDownProcess();else if(bn = runn_bn)/执行进程 this.runProcess();else if(bn = ready_bn)/就绪this.readyProcess();/选择手动或自动模式public void selectModel()create_bn.setEnabled(true);/JOptionPane.showMessageDialog(frame, "选择模式","asd", JOptionPane.WARNING_MESSAGE);/判断自动模式还是手动模式 if(String.valueOf(String)set_auto_manual.getSelectedItem().equals("自动")/是自动模式 model1 = model2; model2 = 1; if(model1 = 0 | model1 = 2)/第一次选择模式或者前一个模式是手动模式 this.autoModel(); else if(String.valueOf(String)set_auto_manual.getSelectedItem().equals("手动") model1 = model2; model2 = 2;/手动模式 this.manualModel(); /选择算法public void selectAlgorithm()if(String.valueOf(String)suanFa.getSelectedItem().equals("先来先服务")/是先来先服务算法algorithm = 1;suanF_lab.setText("先来先服务");else if(String.valueOf(String)suanFa.getSelectedItem().equals("优先级算法")algorithm = 2;suanF_lab.setText("优先级算法");if(List.readyList.size() > 1)/如果就绪队列不为空,调用排序函数this.paiXu();this.refresh_ReadyList();/当"先来先服务算法"转到“优先级算法”,对就绪队列按降序排序public void paiXu()Process process;int n=List.readyList.size();/得到就绪队列的长度for(int i=1;i<=n-1;i+)/比较n-1轮for(int j=0;j<=n-2;j+)if(List.readyList.get(j).getPriority() < List.readyList.get(j+1).getPriority()process = List.readyList.get(j);List.readyList.set(j, List.readyList.get(j+1);List.readyList.set(j+1, process);/进入自动模式public void autoModel()System.out.println("进入自动模式");/判断是否需要刷新按钮if(model1 != model2)/需要刷新wakeUp_bn.setEnabled(true); block_bn.setEnabled(true); shutdown_bn.setEnabled(false); ready_bn.setEnabled(false); runn_bn.setEnabled(false); model1 = model2;if(runStart=false)this.start();runStart = true;System.out.println("退出了自动模式");public void run()threadFlag = true;System.out.println("线程开始");while(true)System.out.println("");/当就绪队列不为空,取出第一个进程执行if(model2 = 1)/是自动模式if(flag)/就绪队列不为空tryif(runningProcess != null)/如果有正在被执行的进程,把进程加入到就绪队列List.readyList.add(runningProcess);this.refresh_ReadyList();/刷新就绪队列的表格runningProcess = null; runningProcess = List.readyList.getFirst();/取出第一个就绪进程top_lab2.setText("进程 "+runningProcess.getName()+".exe 正在执行");System.out.println(runningProcess.getName()+".exe"+"正在执行");List.readyList.removeFirst();/将第一个进程移出就绪队列this.refresh_ReadyList();/刷新就绪队列的表格Thread.sleep(runningProcess.getTime()*1000);runningProcess.num-;/将进程的轮转次数减一 if(runningProcess.num = 0)/如果轮转次数等于0,则结束进程System.out.println("进程"+runningProcess.getName()+"执行完毕");runningProcess = null;if(model2!=2)/线程睡眠期间没有转换到手动模式if(runningProcess!=null)/如果刚刚被执行的进程没有被阻塞 ,就加入到就绪队列if(algorithm = 2)/如果采用了优先级算法,则调用排序函数this.paiXu(runningProcess);else if(algorithm = 1)/如果采用的是先来先服务算法,则直接将进程添加到就绪队列List.readyList.add(runningProcess);/List.readyList.add(runningProcess);this.refresh_ReadyList();/刷新就绪队列的表格runningProcess = null;if(List.readyList.size()=0)/判断据需队列是否为空flag=false;top_lab2.setText("就绪队列为空");elseflag=true;catch(Exception e)/手动模式public void manualModel()System.out.println("进入手动模式");/判断是否需要刷新按钮if(model1 != model2)/需要刷新ready_bn.setEnabled(true);shutdown_bn.setEnabled(true); block_bn.setEnabled(true); runn_bn.setEnabled(true); wakeUp_bn.setEnabled(true); model1 = model2; System.out.println("退出手动模式");/创建进程的函数public void createProcess()/先判断就绪队列是否为满if(List.readyList.size()=11)JOptionPane.showMessageDialog(frame, "【创建进程失败,就绪队列已满】","asd", JOptionPane.WARNING_MESSAGE); return ;String processName = create_tx.getText();/得到进程名/正则表达式验证进程名Pattern p=Ppile("A-Za-z0-9+$"); Matcher m=p.matcher(processName);if(!m.matches()JOptionPane.showMessageDialog(frame, "【创建进程失败,进程名只能由字母和数字组成】","asd", JOptionPane.WARNING_MESSAGE); return;/与正在执行的进程对比,判断进程名是否重复if(runningProcess != null)if(runningProcess.getName().equals(processName)JOptionPane.showMessageDialog(frame, "【创建进程失败,进程重名】","asd", JOptionPane.WARNING_MESSAGE);return;/与就绪队列中的进程对比,判断进程名是否重复for(int i=0;i<List.readyList.size();i+)/遍历就绪队列if(processName.equals(List.readyList.get(i).name) )JOptionPane.showMessageDialog(frame, "【创建进程失败,进程重名】","asd", JOptionPane.WARNING_MESSAGE);return;/与阻塞队列中的进程对比,判断进程名是否重复for(int i=0;i<List.blockList.size();i+)/遍历就绪队列if(processName.equals(List.blockList.get(i).name) )JOptionPane.showMessageDialog(frame, "【创建进程失败,进程重名】","asd", JOptionPane.WARNING_MESSAGE);return;String Time = String.valueOf(String)sdept_com.getSelectedItem();/得到时间片String Priority = String.valueOf(String)priority.getSelectedItem();/得到优先级String Num = String.valueOf(String)num.getSelectedItem();/得到轮转次数int processTime = Integer.parseInt(Time);int processPriority = Integer.parseInt(Priority);int processNum = Integer.parseInt(Num);Process process = new Process();process.setName(processName);process.setTime(processTime);process.setPriority(processPriority);process.setNum(processNum);if(algorithm = 2)/如果采用了优先级算法,则调用排序函数this.paiXu(process);else if(algorithm = 1)/如果采用的是先来先服务算法,则直接将进程添加到就绪队列List.readyList.addLast(process);/将进程加入就绪队列elseJOptionPane.showMessageDialog(frame, "【创建进程失败,请选择调度算法】","asd", JOptionPane.WARNING_MESSAGE);for(int i=0;i<List.readyList.size();i+)/遍历就绪队列,将进程取到tab中datai0=List.readyList.get(i).getName()+".exe"datai1=List.readyList.get(i).getPriority();/刷新就绪队列表格ready_pan.add(scrollPane);flag=true;if(model2 = 1)if(threadFlag = false)this.start();/根据进程优先级算法,给就绪队列的进程排序,如果优先级相同,按先来先服务的方式排序public void paiXu(Process process)if(List.readyList.size() = 0)/如果就绪队列为空,直接添加进程List.readyList.add(process);else/如果就绪队列不为空/进程按照优先级升序排序,将一个进程插入升序排序的就绪队列中去int i,k=0;for(i=0;i<List.readyList.size();i+)if(List.readyList.get(i).getPriority() < process.getPriority()break;k=i;/要插入的位置 List.readyList.addLast(List.readyList.get(List.readyList.size()-1);for(i=List.readyList.size()-1;i>k;i-)List.readyList.set(i, List.readyList.get(i-1);/倒序移动各进程List.readyList.set(k, process);/手动模式下执行线程的函数public void runProcess ()/JOptionPane.showMessageDialog(frame, "执行","asd", JOptionPane.WARNING_MESSAGE);if(flag)/当就绪队列不为空,取出第一个进程执行/判断是否有进程正在执行if(runningProcess != null)/有进程正在执行JOptionPane.showMessageDialog(frame, "执行失败!,有进程正在执行","asd", JOptionPane.WARNING_MESSAGE); return;runningProcess = List.readyList.getFirst();/取出第一个就绪进程top_lab2.setText("进程 "+runningProcess.getName()+".exe 正在执行");System.out.println(runningProcess.getName()+".exe"+"正在执行");List.readyList.removeFirst();/将第一个进程移出就绪队列this.refresh_ReadyList();/刷新就绪队列的表格if(List.readyList.size()=0)/判断据需队列是否为空flag=false;/top_lab2.setText("就绪队列为空");elseflag=true;elseJOptionPane.showMessageDialog(frame, "执行失败!,没有可执行的进程","asd", JOptionPane.WARNING_MESSAGE);/在手动