资源分配和管理的银行家算法-银行家算法实验报告.doc
操作系统实验报告年级、专业、班级姓名实验题目资源分配和管理的银行家算法实验时间 2013.05.14实验地点主教0416实验成绩 实验性质验证性 设计性 综合性教师评价:算法/实验过程正确; 源程序/实验内容提交 程序结构/实验步骤合理;实验结果正确; 语法、语义正确; 报告规范; 其他: 评价教师签名:一、实验目的学习分配和管理资源的银行家算法,了解死锁避免方法。二、实验项目内容编写程序实现教材6.3.2节的银行家算法程序功能:1. 程序随机生成进程数量(>10)、资源种类(>3)、每类资源总数量(>3)、进程的申请资源的数量(>0)、已分配资源的数量、可用资源数量等;2. 输出每一个进程的资源分配情况;3. 输出每一步的资源分配情况和进程执行序列(安全序列)。4. 指出每一次资源分配后系统是否处于安全状态。三、实验过程或算法(源程序)31算法思路: 先对用户提出的请求进行合法性检查,即检查请求是否大于需要的,是否大于可利用的。若请求合法,则进行预分配,对分配后的状态调用安全性算法进行检查。若安全,则分配;若不安全,则拒绝申请,恢复到原来的状态,拒绝申请。32银行家算法步骤(1)如果Requesti=Need,则转向步骤(2);否则,认为出错,因为它所需要的资源数已超过它所宣布的最大值。(2)如果Requesti=Available,则转向步骤(3);否则,表示系统中尚无足够的资源,进程必须等待。(3)系统试探把要求的资源分配给进程Pi,并修改下面数据结构中的数值: Available=Available-Requesti; Allocation=Allocation+Request; Need=Need-Request;(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。33安全性算法步骤(1)设置工作向量工作向量Work。它表示系统可提供进程继续运行所需要的各类资源数目,执行安全算法开始时,Work=Available;定义判断一个进程是否执行完毕的方法:boolean isFinished()。(2)从进程集合中找到一个能满足下述条件的进程:process.isFinished()返回值为true.Need<=Work如找到,执行步骤(3);否则,执行步骤(4)。(3)当进程P获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:Work=Work+Allocation;Allocation += Need; 转向步骤(2)。(4)如果所有进程的均执行完毕即isAllFinished()返回值为true,则表示系统处于安全状态;否则,系统处于不安全状态。34数据结构:34. 1主要用到的数据结构:(1) 保存进程最大资源需求量的矩阵: int _maxNeed(2) 保存进程已分配资源量的矩阵: int _allocated(3) 保存进程标识符的字符串:String _id(4) 保存系统中各资源总数的矩阵:int _totalResource(5) 表示申请资源的进程队列:ArrayList<Process> _processes(6) 表示系统资源种类数的整数:int _resourceClassCount(7) 存储执行信息:StringBuffer _executeInfo34. 2程序模块: 代表进程的类:Process.java代表银行家算法的类:BankerAlgorithm.java算法的主界面:BankerUI.java34. 3各模块间的调用关系:BankerUI是程序执行的主界面,输入系统资源种类数之后,其通过程序随机生成进程数量(>10)、资源种类(>3)、每类资源总数量(>3)、进程的申请资源的数量(>0)、已分配资源的数量、可用资源数量等。其中所用针对系统进程和资源的操作均需要调用类BankerAlgorithm的方法。3.5主要函数的核心代码:1. 进行初始化输入的函数2. 打印输出的函数3. 利用安全性算法进行检测的函数4. 进行资源分配的函数5. 利用行家算法进行判定的函数 注:具体代码请见附录源程序清单。程序流程图:1、 系统主要过程流程图: 2、进程请求资源序列图 3、安全性算法序列图四、实验结果及分析和(或)源程序调试过程 4.1 主界面: 4.2点击“随机生成”按钮,随机生成进程数量(>10)、资源种类(>3)、每类资源总数量(>3)、进程的申请资源的数量(>0)、已分配资源的数量、可用资源数量,并向系统中添加进程,显示进程的资源分配情况。 4.3点击“分配资源”按钮,检查系统是否安全,如果当前系统安全,则输出安全队列,并给第一个安全进程分配资源。若安全:若不安全,则“执行结果”提示框会提示:4.4点击“执行进程”按钮,执行已经分配资源的进程,并将其从队列中移除。4.5点击“分配资源”按钮,重新检测当前系统的安全,如果当前系统安全,则输出安全队列,并给第一个安全进程分配资源。4.6 此后重复4、5步,直至系统中的进程执行完毕:4.7 系统中此时已没有等待执行的进程,若再点击“分配资源”按钮,则“执行结果”提示框中会提示:4.8 如果需要再进行模拟,则点击“重新生成”按钮,会重新生成进程,再重复前7步即可。4.9 如果模拟结束,可点击“退出”按钮,即可退出系统。 模拟结束。五、心得体会通过本次实验,我们对银行家算法有了更深的了解,理解了操作系统关于进程调度的一些方法,并通过编程实现了该算法。也进一步提高了我们的编程能力,从中学会了很多。附录:源程序清单1.主界面类BankerUI.javapublic class BankerUI extends JFrame implements ActionListener private static final long serialVersionUID = -8004544916653049326L;private JPanel panel;private JButton model;private JButton alloc;private JButton next;private JButton exit;private JTextField processNum;/ centerprivate JEditorPane resourcesInfo;private JEditorPane processesInfo; / 用html格式显示进程需要资源个数.private JTextArea result;private JSplitPane splitCenter;private JPanel east;private int resourceClassesCount;/ 表示资源的个数private BankerAlgorithm banker;/private Process pro;private int Pronum = 0;private int Sournum = 0;static int available = null;/ 可利用的资源 static int max = null;/ 最大的需求矩阵 static int allocation = null;/ 分配矩阵 static int need = null;/ 需求矩阵static int totalSour = null; static int Max = null; static int Allocation = null;public BankerUI() super("银行家算法");try UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); catch (ClassNotFoundException e) e.printStackTrace(); catch (InstantiationException e) e.printStackTrace(); catch (IllegalAccessException e) e.printStackTrace(); catch (UnsupportedLookAndFeelException e) e.printStackTrace();setBounds(100, 100, 800, 600);panel = new JPanel(new BorderLayout();/ centerresourcesInfo = new JEditorPane("text/html", "<html></html>");resourcesInfo.setEditable(false);processesInfo = new JEditorPane("text/html", "<html></html>"); / 以html格式显示进程信息.processesInfo.setEditable(false);JSplitPane splitInfo = new JSplitPane(JSplitPane.VERTICAL_SPLIT);splitInfo.add(new JScrollPane(resourcesInfo), JSplitPane.TOP);splitInfo.add(new JScrollPane(processesInfo), JSplitPane.BOTTOM);splitInfo.setBorder(BorderFactory.createTitledBorder("系统信息");splitInfo.setOneTouchExpandable(true);result = new JTextArea(5, 30);result.setEditable(false);result.setWrapStyleWord(true); / 按单词换行,即所有单词都不会打断.result.setLineWrap(true); / 换行.JScrollPane textScroll = new JScrollPane(result);textScroll.setBorder(BorderFactory.createTitledBorder("执行结果");splitCenter = new JSplitPane(JSplitPane.VERTICAL_SPLIT);splitCenter.setResizeWeight(1.0);splitCenter.add(splitInfo, JSplitPane.TOP);splitCenter.add(textScroll, JSplitPane.BOTTOM);splitCenter.setOneTouchExpandable(true); / 点击一下就可以扩展分割开来的控件.panel.add(splitCenter, BorderLayout.CENTER);panel.setSize(800, 700);/ easteast = new JPanel();/east.setSize(60, 100);model = new JButton("随机生成");model.setSize(50, 20);model.setLocation(10, 10);model.addActionListener(this);alloc = new JButton("分配资源");alloc.addActionListener(this);next = new JButton("执行进程");next.addActionListener(this);exit = new JButton("退出");exit.addActionListener(this);JLabel label = new JLabel("当前进程个数:");label.setSize(50,20);label.setLocation(10, 60);processNum = new JTextField();processNum.setSize(50, 20);processNum.setLocation(10,90);processNum.setEditable(false);processNum.setFont(new Font("宋体", Font.BOLD, 20);processNum.setForeground(Color.RED);processNum.setHorizontalAlignment(JTextField.CENTER);east.setLayout(new GridLayout(10,1,10,10);east.setSize(80, 100);east.add(label);east.add(processNum);east.add(model);east.add(alloc);east.add(next);east.add(exit);panel.add(east, BorderLayout.EAST);setEastButtonEnabled(false);/this.getContentPane().add(new JScrollPane(panel);this.getContentPane().add(panel);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);public void setEastButtonEnabled(boolean b) / eastalloc.setEnabled(b);next.setEnabled(b);public BankerAlgorithm getBanker() return banker;/ 一个数组小于另一个数组,两个数组大小相等.public boolean aLowerB(int a, int b) for (int i = 0; i < a.length; i+) if (ai > bi)return false;return true;/ 在resourceInfoz中显示系统资源的信息.private void updateTotalResourcesInfo() StringBuffer html = new StringBuffer(100);html.append("<html><body>");html.append("<table width = "100%" border = "1" bgcolor="#C0C0C0" bordercolor="#000000">n");StringBuffer resourceNames = new StringBuffer("<tr><td>资源名</td>");StringBuffer resourceCounts = new StringBuffer("<tr><td>资源个数</td>");/int totalResource = banker.getTotalResource();for (int i = 0; i < Sournum; i+) resourceNames.append("<td>");resourceNames.append("R" + String.valueOf(i);resourceNames.append("</td>");resourceCounts.append("<td>");resourceCounts.append(String.valueOf(totalSouri);resourceCounts.append("</td>");resourceNames.append("</tr>");resourceCounts.append("</tr>");html.append(resourceNames);html.append(resourceCounts);html.append("</table>n</body>n</html>");resourcesInfo.setText(html.toString();private void updateProcessInfo() StringBuffer content = new StringBuffer("<html>n");content.append("<body>n");content.append("<table width = "100%" border = "1" bgcolor="#C0C0C0" bordercolor="#000000">n");content.append("<tr><td>资源情况</td><td align = "center" colspan = "+ Sournum+ ">Max</td><td align = "center" colspan = "+ Sournum+ ">Allocated</td><td align = "center" colspan = "+ Sournum+ ">Need</td><td align = "center" colspan = "+ Sournum + ">Avilable</td></tr>");content.append("<tr>");content.append("<td>进程名</td>");StringBuffer processNames = new StringBuffer(40);for (int i = 0; i < Sournum; i+) processNames.append("<td>R" + i + "</td>");content.append(processNames); / Maxcontent.append(processNames); / Allocatedcontent.append(processNames); / Needcontent.append(processNames); / Avilablecontent.append("</tr>");ArrayList<Process> processes = banker.getProcesses();/System.out.println("pppp"+processes.size();for (int i = 0; i < processes.size(); i+) Process p = processes.get(i);content.append("<tr>" + p.makeHtml();if (i = 0) int avilable = banker.getAvilable();for (int j = 0; j < avilable.length; j+)content.append("<td>" + avilablej + "</td>");if (i = 1)content.append("<td rowspan ="+ String.valueOf(processes.size() - 1)+ " colspan = "3"></td>");content.append("</tr>");content.append("</table>n");content.append("</body>n");content.append("</html>");processesInfo.setText(content.toString();processNum.setText(""+Pronum);Overridepublic void actionPerformed(ActionEvent e) if (e.getSource() = model) RandomMake();banker = new BankerAlgorithm(totalSour,Sournum, new ArrayList<Process>();for (int i = 0; i < Pronum; i+) Max = new intSournum;Allocation = new intSournum;for (int j = 0; j < Sournum; j+) Maxj = maxij;Allocationj = allocationij;Process pro = new Process(String.valueOf(i),Max,Allocation,Sournum);if (banker.addProcess(pro) result.setText(result.getText() + "成功添加进程: "+ banker.getExecuteInfo(); else result.setText(result.getText() + "添加进程失败: "+ banker.getExecuteInfo();return;/updateProcessInfo();updateTotalResourcesInfo(); / 更新系统资源信息.updateProcessInfo(); / 更新系统进程资源信息.alloc.setEnabled(true);next.setEnabled(false);model.setText("重新生成");if (e.getSource() = alloc) String names = banker.getProcessNames();if (names.length = 0) result.setText(result.getText() + "当前系统中没有进程,无法分配资源!n");next.setEnabled(false);return;if (banker.isSecured() String id = banker.AllocationResourse();result.setText(result.getText() + "进程P"+id+"资源分配成功!n" +"当前系统是安全的.n安全序列: "+ banker.getExecuteInfo();updateProcessInfo(); / 更新系统进程资源信息.next.setEnabled(true); else result.setText(result.getText() +"资源分配失败!n"+ "当前系统是不安全的.n详细信息如下: "+ banker.getExecuteInfo();next.setEnabled(false);return;if (e.getSource() = next) String pid = banker.ExecuteProcess();if(Pronum > 0)Pronum-;updateProcessInfo();result.append("进程P"+pid+"执行完毕!n");else JOptionPane.showMessageDialog(this, "系统中所有进程已执行完毕!", "提示:", JOptionPane.ERROR_MESSAGE); next.setEnabled(false);next.setEnabled(false);if (e.getSource() = exit) if (JOptionPane.showConfirmDialog(this, "退出系统?", "确定退出",JOptionPane.OK_CANCEL_OPTION) = JOptionPane.OK_OPTION)System.exit(0);return;public void RandomMake()Random rnd = new Random();Pronum = rnd.nextInt(10)+10;Sournum = rnd.nextInt(5)+3;available = new intSournum;max = new intPronumSournum;allocation = new intPronumSournum;need = new intPronumSournum;for (int i = 0; i < Sournum; i+) availablei = rnd.nextInt(5) + 3;for (int i = 0; i < Pronum; i+) for (int j = 0; j < Sournum; j+) allocationij = rnd.nextInt(5);/ 分配矩阵获得随机数for (int i = 0; i < Pronum; i+) for (int j = 0; j < Sournum; j+) do maxij = rnd.nextInt(10);/ 最大的需求矩阵获得随机数,且要比分配矩阵相同位置的数大 while (maxij < allocationij);need = new intPronumSournum;for (int i = 0; i < Pronum; i+) for (int j = 0; j < Sournum; j+) needij = maxij - allocationij;totalSour = new intSournum;for (int i = 0; i < Sournum; i+) totalSouri=availablei;for (int i = 0; i < Pronum; i+) for (int j = 0; j < Sournum; j+) totalSourj+= allocationij;public static void main(String args) throws ClassNotFoundException,InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException BankerUI banker = new BankerUI(); banker.setVisible(true); 2.银行家算法实现类 BankerAlgorithm.javapublic class BankerAlgorithm / 表示系统中资源种类数/private int saveProcess;private int savePNum = 0;private final int _resourceClassesCount;private final int _totalResource;private ArrayList<Process> _processes = new ArrayList<Process>();private ArrayList<Process> saveProcesses = new ArrayList<Process>();private StringBuffer _executeInfo = new StringBuffer(50);public BankerAlgorithm(int totalResource, int resourceClassesCount,ArrayList<Process> processes) _resourceClassesCount = resourceClassesCount;_totalResource = totalResource;_processes = processes;private ArrayList<Process> newProcesses() ArrayList<Process> pList = new ArrayList<Process>();for (Process p : _processes) pList.add(p.newProcess();return pList;public int getAvilable() int avilable = new int_resourceClassesCount;for (int i = 0; i < _resourceClassesCount; +i) avilablei = _totalResourcei - getResourceAllocated(i);return avilable;/ index代表某个资源的索引,结果为某个资源的已分配量.private int getResourceAllocated(int index) int totalAllocated = 0;for (Process p : _processes) int allocated = p.getAllocated();totalAllocated += allocatedindex;return totalAllocated;public boolean addProcess(Process p) if (isUniqueProcessId(p.getId() _executeInfo.append(p.getId() + "=" + p.toString();return _processes.add(p); else _executeInfo.append(