1、1题目:编程模拟多进程共享临界资源 班级: 0 姓名: 0 学号: 0 指导教师: 0 2011 年 12 月综合实践评分表班级 0 姓名 0 指导教师 02题目:编程演示多进程共享临界资源 评分标准评分的依据评分标准 分数权重 A C 得分选题 10选题符合大纲要求,题目较新颖,工作量大选题基本符合大纲要求,工作量适中工作态度 10态度端正,能主动认真完成各个环节的工作,不迟到早退,出勤好。能够完成各环节基本工作,出勤较好。存储结构、算法描述 20能正确选择存储结构,定义准确,算法流程图或类 C 语言描述的算法准确无误能正确选择存储结构,算法流程图或类 C 语言描述的算法基本准确独立解决问题
2、的能力 10具有独立分析、解决问题能力,有一定的创造性,能够独立完成软件的设计与调试工作,程序结构清晰,逻辑严谨,功能完善。有一定的分析、解决问题能力。能够在老师指导下完成软件的设计与调试工作,程序功能较完善。答辨问题回答 20 能准确回答老师提出的问题 能基本准确回答老师提出的问题程序运行情况 10程序运行正确、界面清晰,测试数据设计合理。程序运行正确、界面较清晰,能给出合适的测试数据。综合实践报告 20格式规范,层次清晰,设计思想明确,解决问题方法合理,体会深刻。格式较规范,设计思想基本明确,解决问题方法较合理。总分指导教师(签字):注:介于 A 和 C 之间为 B 级,低于 C 为 D
3、级和 E 级。按各项指标打分后,总分在 90100 为优,8089 为良,7079 为中,6069 为及格,60 分以下为不及格。3编程演示多进程共享临界资源摘要:一般我们在java中运行其它类中的方法时,无论是静态调用,还是动态调用,都是在当前的进程中执行的,也就是说,只有一个 java虚拟机实例在运行。而有的时候,我们需要通过java代码启动多个java子进程。这样做虽然占用了一些系统资源,但会使程序更加稳定,因为新启动的程序是在不同的虚拟机进程中运行的,如果有一个进程发生异常,并不影响其它的子进程。在Java中我们可以使用两种方法来实现这种要求。最简单的方法就是通过Runtime中的ex
4、ec方法执行java classname。如果执行成功,这个方法返回一个Process对象,如果执行失败,将抛出一个IOException错误。关键字:多进程 临界区 资源 1,引言以前古老的 DOS 操作系统(V 6.22)是单任务的,还没有线程的概念,系统在每次只能做一件事情。比如你在 copy 东西的时候不能 rename 文件名。为了提高系统的利用效率,采用批处理来批量执行任务。现在的操作系统都是多任务操作系统,每个运行的任务就是操作系统所做的一件事情,比如你在听歌的同时还在用 MSN 和好友聊天。听歌和聊天就是两个任务,这个两个任务是“同时”进行的。一个任务一般对应一个进程,也可能包
5、含好几个进程。比如运行的 MSN 就对应一个 MSN 的进程,如果你用的是windows 系统,你就可以在任务管理器中看到操作系统正在运行的进程信息。一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程。启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。实际上,这样的代码块就是线程体。线程是进程中乱序执行的代码流程。当多个线程同时运行的时候,这样的执行模式成为并发执行。多线程的目的是为了最大限度的利用 CPU 资源。4Java 编写程序都运行在在 J
6、ava 虚拟机(JVM)中,在 JVM 的内部,程序的多任务是通过线程来实现的。每用 java 命令启动一个 java 应用程序,就会启动一个 JVM 进程。在同一个 JVM 进程中,有且只有一个进程,就是它自己。在这个 JVM 环境中,所有程序代码的运行都是以线程来运行。一般常见的 Java 应用程序都是单线程的。比如,用 java 命令运行一个最简单的 HelloWorld 的 Java 应用程序时,就启动了一个 JVM 进程,JVM 找到程序程序的入口点 main(),然后运行 main()方法,这样就产生了一个线程,这个线程称之为主线程。当 main 方法结束后,主线程运行完成。JVM
7、 进程也随即退出。对于一个进程中的多个线程来说,多个线程共享进程的内存块,当有新的线程产生的时候,操作系统不分配新的内存,而是让新线程共享原有的进程块的内存。因此,线程间的通信很容易,速度也很快。不同的进程因为处于不同的内存块,因此进程之间的通信相对困难。实际上,操作的系统的多进程实现了多任务并发执行,程序的多线程实现了进程的并发执行。多任务、多进程、多线程的前提都是要求操作系统提供多任务、多进程、多线程的支持。在 Java 程序中,JVM 负责线程的调度。线程调度是值按照特定的机制为多个线程分配 CPU 的使用权。调度的模式有两种:分时调度和抢占式调度。分时调度是所有线程轮流获得 CPU 使
8、用权,并平均分配每个线程占用 CPU 的时间;抢占式调度是根据线程的优先级别来获取 CPU 的使用权。JVM 的线程调度模式采用了抢占式模式。所谓的“并发执行”、“同时”其实都不是真正意义上的“同时”。众所周知,CPU 都有个时钟频率,表示每秒中能执行 cpu 指令的次数。在每个时钟周期内,CPU 实际上只能去执行一条(也有可能多条)指令。操作系统将进程线程进行管理,轮流(没有固定的顺序)分配每个进程很短的一段是时间(不一定是均分),然后在每个线程内部,程序代码自己处理该进程内部线程的时间分配,多个线程之间相互的切换去执行,这个切换时间也是非常短的。因此多任务、多进程、多线程都是操作系统给人的
9、一种宏观感受,从微观角度看,程序的运行是异步执行的。52,需求分析要求产生 3 个进程:(1)两个进程模拟需要进入临界区的用户进程,当需要进入临界区时,显示:“进程 x 请求进入临界区” ,同时向管理进程提出申请;申请返回,表示进入了临界区。在临界区中等待一段随机时间,并显示:“进程 x 正在临界区” ;当时间结束,显示:“进程 x 退出临界区” ,同时向管理进程提出退出申请;当申请返回,显示:“进程 x 已退出临界区。 ”(2)一个进程作为原语的管理进程,接受其他进程的临界区进入请求:如果允许进入,则设置相应变量,然后返回;如果不允许进入,则进入循环等待,直到允许为止;(3)对临界区的访问应
10、遵循空闲让进、忙则等待、有限等待、让权等待的准则。(4)进程间通信可以采用信号、消息传递、管道或网络通信方式。3,实现原理通过编写,创建两个进程模拟需要进入临界区,另外编写一个进程作为原语的管理进程,其负责两个进程的进入!接着设置一个临界区,让其进程在其中访问遵循空闲让进、忙则等待、有限等待、让权等待的准则。当进程和临界区建立好后,临界区的数据传输,受到了系统硬件的支持,不耗费多余的资源;而进程间通信传递,由软件进行控制和实现,需要消耗一定的CPU 资源。从这个意义上讲,临界区更适合频繁和大量的数据传输。进程信息的传递,自身就带有同步的控制。当等到信息的时候,进程进入睡眠状态,不再消耗 CPU
11、 资源。而共享队列如果不借助其他机制进行同步,接收数据的一方必须进行不断的查询,白白浪费了大量的 CPU 资源。3,算法实现模型图6图 1 算法实现模型图5,算法实现流程图(1)进程状态转换进程的状态反映进程执行进程的变化。这些状态随着进程的执行和外界条件发生变化和转换。下图给出了有一个基本状态,即就绪状态、执行状态与等待状态之间的转换关系。图 2 进程状态转换(2)PCB 的组织方式PCB 的组织方式将处于同一状态的进程组织在一起。 链表:同一状态的进程其 PCB 成一链表,多个状态对应多个不同的链表各状态的进程形成不同的链表:就绪链表、阻塞链表索引表:同一状态的进程归入一个 index 表
12、(由 index 指向 PCB) ,多个状7态对应多个不同的 index 表各状态的进行形成不同的索引表:就绪索引表、阻塞索引表图 3 PCB 的组织方式(3)进程队列为了实现对进程的管理,系统将所有进程的 PCB 排成若干个队列,称为进程队列。(4)唤醒原语当等待队列中的进程所等待的事件发生时,等待该事件的所有进程都将被唤醒。显然,一个处于阻塞状态的进程不可能自己唤醒自己(为什么?)唤醒一个进程有两种方法:一种是由系统进程唤醒。另一种是由事件发生进程唤醒。当由系统进程唤醒等待进程时,系统进程统一控制事件的发生并将“事件发生”这一消息通知等待进程。从而使得该进程因等待事件已发生而进入就绪队列。
13、等待进程也可由事件发生进唤醒。由事件发生进程唤醒时,事件发生进程和被唤醒进程之间是合作关系。因此,唤醒原语既可被系统进程调用,也可被事件发生进程调用。我们称调用唤醒原语的进程为唤醒进程。唤醒原语首先将被唤醒进程从相应的等待队列中摘下,将被唤醒进程置为就绪状态之后,送入就绪队列。在把被唤醒进程送入就绪队列之后,唤醒原语既可以返回原调用程序,也可以转向进程调度,以便让调度程序有机会选择一个合适的进程执行。8图 4 左-阻塞原语 右-唤醒原语6,软件运行环境及限制只能在配有 JDK1.6 以上、JBuilder 、JCreator、Java WorkShop 、Visual Age for Java
14、 等环境中运行。8,测试数据图 5 测试数据9,8,结果输出及分析(1)输入线程名,点击开始,如图:图 6 输入线程名(2)输出结果,分析,如图:图 7 输出结果 分析10(3)退出:图 8 退出9,心得体会通过这次课程设计,我们更进一步的熟悉计算机操作系统的内涵,同时也对 java 语法和 java 语言的面向对象特性一定的理解,更加深和理解面向对象的基本概念和面向对象程序设计的基本原理;培养了我们对这些原理和设计原则进行面向对象的系统设计和开发;提高我们的编程能力,培养我们利用面向对象的开发方法进行系统开发的技巧和良好的程序设计风格;使我们进一步学习和利用软件工程思想进行软件开发和软件文档
15、的编制。操作系统是用户和计算机硬件之间的桥梁,用户通过软件向操作系统提交作业,每个作业有一个或多个进程组成。所以本设计模拟实现计算机的主要功能,实现计算机的模拟进程调度与共享临界资源。本模拟操作系统由三个系统进程组成,由原语管理所有的子进程和总的内存和资源分配,两个进程对临界区进行申请资源和占有。而管理进程(原语)和子进程都是一个类的对象,不同的是系统进程由程序自动初始化和运行,而子进程须由模拟用户提交。在这次编制中,我学会了很多东西,也找出了自己的一些不足。通过这次我又加深了不少;其次是各个功能的算法,以前还是很模糊,现在总算有领悟啦;再次是整个工程的全局把握还不够,有时遗漏忘点,不过在队友
16、的提醒和11帮助下还是有所进步;最后也很高兴完成了设计。10,参考文献1 汤子瀛 哲凤屏 汤小丹计算机操作系统 (修订版)西安电子科技大学出版社 20042 威格尔斯沃恩java 程序设计高级教程 (第 3 版)清华大学出版社 20053 斯 科 特 ( 美 ) 程序设计语言实践之路电子工业出版社 20054 胡伏湘 雷军环等Java 程序设计使用教程清华大学出版社 20095 朱战立数据结构java 语言描述清华大学出版社 20056 王晓东计算机算法设计与分析电子工业出版社 2007源程序代码:public class MainFrame extends JFrame implements
17、 FocusListenerJTextArea jta=new JTextArea();static JTextField jtf=new JTextField2;static JButton jb=new JButton2;12ThreadShow ts= new ThreadShow();/界面设计public MainFrame()super(“模拟多进程共享临界资源“);JLabel jl=new JLabel2;for(int i=0;ijtf.length;i+)jtfi=new JTextField(12);jtfi.addFocusListener(this);/设置按钮名称和
18、位置jl0=new JLabel(“第一线程的名称 : “);jl1=new JLabel(“第二线程的名称 : “);jb0=new JButton(“模拟开始“);jb1=new JButton(“模拟结束“);JMenuBar mb = new JMenuBar();JMenu jm1 = new JMenu(“文件(F)“);JMenu jm2 = new JMenu(“编辑(E)“);JMenu jm3 = new JMenu(“查看(V)“);JMenu jm4 = new JMenu(“帮助(H)“);JMenuItem jmia1=new JMenuItem(“打开(Ctrl+
19、O)“);JMenuItem jmia2=new JMenuItem(“保存(Ctrl+S)“);JMenuItem jmia3=new JMenuItem(“打印(Ctrl+P)“);JMenuItem jmia4=new JMenuItem(“退出(C)“);JMenuItem jmib1=new JMenuItem(“撤消(Ctrl+Z)“);JMenuItem jmib2=new JMenuItem(“全选(Ctrl+A)“);JMenuItem jmic1=new JMenuItem(“工具栏(T)“);JMenuItem jmic2=new JMenuItem(“状态栏(B)“);
20、JMenuItem jmic3=new JMenuItem(“刷新(R)“);JMenuItem jmid1=new JMenuItem(“帮助主题(H)“);JMenuItem jmid2=new JMenuItem(“关于软件(A)“);jmia4.addMouseListener(new MouseAdapter() public void mousePressed(MouseEvent e) 13System.exit(0); );jmic3.addMouseListener(new MouseAdapter() public void mousePressed(MouseEvent
21、e) for(int i=0;ijtf.length;i+)jtfi.setText(“); );jmid1.addMouseListener(new MouseAdapter() public void mousePressed(MouseEvent e) JOptionPane.showMessageDialog(new JOptionPane(), “XXXXXXX“, “提示!“, JOptionPane.INFORMATION_MESSAGE););jmid2.addMouseListener(new MouseAdapter() public void mousePressed(M
22、ouseEvent e) JOptionPane.showMessageDialog(new JOptionPane(), “XXXXXXX“, “提示!“, JOptionPane.INFORMATION_MESSAGE););Container cont=this.getContentPane();cont.setLayout(new BorderLayout();JPanel jp1=new JPanel();JPanel jp2=new JPanel();jp1.setLayout(new GridLayout(0,1);jp1.add(mb);mb.add(jm1);mb.add(j
23、m2);mb.add(jm3);14mb.add(jm4);jm1.add(jmia1);jm1.add(jmia2);jm1.add(jmia3);jm1.addSeparator();jm1.add(jmia4);jm2.add(jmib1);jm2.add(jmib2);jm3.add(jmic1);jm3.add(jmic2);jm3.addSeparator();jm3.add(jmic3);jm4.add(jmid1);jm4.addSeparator();jm4.add(jmid2);for(int i=0;ijtf.length;i+)JPanel temp=new JPane
24、l();temp.add(jli);temp.add(jtfi);jp1.add(temp);for(int i=0;ijb.length;i+)jp2.add(jbi);jp1.add(jp2);jp1.setBorder(new LineBorder(new Color(0,0,0),10);jp1.setBorder(new LineBorder(new Color(238,238,238),10);cont.setLayout(new BorderLayout();cont.add(jp1,BorderLayout.NORTH);jta.setEnabled(true);15JScro
25、llPane js=new JScrollPane(jta,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED );jta.setBorder(new LineBorder(new Color(34,57,12),1);js.setBorder( new LineBorder(new Color(238,238,238),10);cont.add(js,BorderLayout.CENTER);this.setSize(335,435);/定义界面大小t
26、his.setDefaultCloseOperation(3);/设置当前界面显示时相对屏幕的位置this.setLocation(Toolkit.getDefaultToolkit().getScreenSize().width/2-175 ,Toolkit.getDefaultToolkit().getScreenSize().height/2-200);this.setResizable(false); this.setVisible(true);/jb1 添加监听器jb1.addActionListener(new ActionListener()public void actionP
27、erformed(ActionEvent arg0)if(ts.tu1!=nullif(ts.tu2!=nullSystem.exit(0); );/jb0 添加监听器jb0.addActionListener(new ActionListener()public void actionPerformed(ActionEvent arg0)for(int i=0;ijtf.length;i+)jtfi.setEditable(false);MainFrame.jb0.setEnabled(false);jta.setText(“);ts.run(jtf0.getText().trim(),jt
28、f1.getText().trim(),jta); );public static void main(String ares)new MainFrame();16public void focusGained(FocusEvent arg0) /当用户点击文本框时,文本框就把当前内容清空JTextField jtf=(JTextField)arg0.getSource();jtf.setText(“);public void focusLost(FocusEvent arg0) /临界区class ThreadManager implements Runnable /指向要管理得临界资源 T
29、hingSome obj;/记录 obj 是否已有使用者 boolean jud = false;Vector vec = new Vector();String name;public ThreadManager(ThingSome ts) obj = ts;public void run() while (vec.size() != 0) for (int i = 0; i vec.size(); i+) if (!(Thread) vec.get(i).isAlive() (Thread) vec.get(i).interrupt();vec.remove(i);try Thread.c
30、urrentThread().sleep(100); catch (InterruptedException e) e.printStackTrace();17JOptionPane.showMessageDialog(null, “演示完毕“, “ 信息“,/结束窗口JOptionPane.INFORMATION_MESSAGE);for (int i = 0; i MainFrame.jtf.length; i+) MainFrame.jtfi.setText(“);MainFrame.jtfi.setEditable(true);MainFrame.jb0.setEnabled(true
31、);public void addThreadUser(ThreadUser user) vec.add(user);/进程控制块public void take(Thread user) System.out.println(“进程 “ + user.getName() + “ 请求资源 .“);obj.jta.append(“进程 “ + user.getName() + “ 请求资源 .n“);/ 如果 jud 为 true,表示有线程正在使用资源,jud 为 false,表示资源没有被使用while (jud) try System.out.println(“进程 “ + user.g
32、etName() + “ 等待资源.“);obj.jta.append(“进程 “ + user.getName() + “ 等待资源.n“);synchronized (obj) / 进入资源的等待池中,等待被唤醒obj.wait(); catch (InterruptedException e) System.out.println(“进程 “ + user.getName() + “ 进入临界区 .“);obj.jta.append(“进程 “ + user.getName() + “ 进入临界区 .n“);jud = true;/ 使用资源obj.useing(user);jud = false;18System.out.println(“进程 “ + user.getName() + “ 已退出临界区 “);obj.jta.append(“进程 “ + user.getName() + “ 已退出临界区 n“);synchronized (obj) / 把资源等待池中的线程唤醒obj.notifyAll();