临界区资源模拟.docx
《临界区资源模拟.docx》由会员分享,可在线阅读,更多相关《临界区资源模拟.docx(24页珍藏版)》请在冰豆网上搜索。
临界区资源模拟
课程设计说明书
计算机操作系统课程设计
院系:
计算机科学与工程学院
专业班级:
学号:
学生姓名:
指导教师:
2013年11月29日
安徽理工大学课程设计(论文)任务书
计算机科学与工程院系
学号
学生姓名
专业(班级)
设计题目
临界区资源模拟
设
计
技
术
参
数
1.实现UP、DOWN原语
2.产生3个进程,两个进程模拟需要进入临界区的用户进程。
当需要进入临界区时,显示:
“进程x请求进入临界区…”,同时向管理进程提出申请;
申请返回,表示进入了临界区。
在临界区中等待一段随机时间,并显示:
“进程x正在临界区…”;
当时间结束,显示:
“进程x退出临界区…”,同时向管理进程提出退出申请;
当申请返回,显示:
“进程x已退出临界区。
”
3.一进程作为原语的管理进程,接受其他进程的临界区进入请求。
设
计
要
求
建立三个进程,模拟进入临界区,然后用一个进程进行管理,另外两个进程模拟用户进程进入临界区。
工
作
量
1、课程设计说明书2000字。
2、画流程图,编写程序代码。
3、调试执行。
工
作
计
划
1、首先认真研究老师所给的题目,了解题目要求做什么。
2、查阅资料,解决问题。
3、编写源程序并调试之。
4、写课程设计说明书。
参
考
资
料
[1]郑莉编著,《Java语言程序设计》,清华大学出版社
[2]汤小丹、梁红兵、哲凤屏、汤子瀛编著,《计算机操作系统》,西安电子科技大学出版社
指导教师签字
系主任签字
年月日
指导教师评语:
成绩:
指导教师:
年月日
安徽理工大学课程设计(论文)成绩评定表
摘要
一般我们在java中运行其它类中的方法时,无论是静态调用,还是动态调用,都是在当前的进程中执行的,也就是说,只有一个java虚拟机实例在运行。
而有的时候,我们需要通过java代码启动多个java子进程。
这样做虽然占用了一些系统资源,但会使程序更加稳定,因为新启动的程序是在不同的虚拟机进程中运行的,如果有一个进程发生异常,并不影响其它的子进程。
在Java中我们可以使用两种方法来实现这种要求。
最简单的方法就是通过Runtime中的exec方法执行javaclassname。
如果执行成功,这个方法返回一个Process对象,如果执行失败,将抛出一个IOException错误。
在临界区资源模拟程序设计中,一个进程作为原语的管理进程,接受其他进程的临界区进入请求:
要建立三个进程,模拟进入临界区,然后用一个进程进行管理。
从而实现UP、DOWN原语,程序中产生3个进程,两个进程模拟需要进入临界区的用户进程。
当需要进入临界区时,显示:
“进程x请求进入临界区…”,同时向管理进程提出申请;申请返回,表示进入了临界区。
在临界区中等待一段随机时间,并显示:
“进程x正在临界区…”;当时间结束,显示:
“进程x退出临界区…”,同时向管理进程提出退出申请;当申请返回,显示:
“进程x已退出临界区。
”
关键字:
java临界区进程
目录
1.课题分析1
1.1问题定义1
1.2可行性研究1
1.3需求分析1
2.课题总体设计2
2.1实验原理2
2.2开发环境2
2.3程序结构2
2.4程序流程图4
2.5程序的体系结构5
3.课题详细设计6
3.1界面设计代码6
3.2临界区及进程管理模块设计代码9
3.3临界资源设计11
3.4设定一个进程作为原语的管理的进程,接受其他进程的临界区进入请求12
3.5通信快设计,两个进程模拟用户进程进行通信12
3.6程序跟踪测试13
4.总结17
4.1设计体会17
4.2系统改进17
参考文献18
1.课题分析
根据课程设计的题目,首先是问题定义阶段,明确课程设计的要求及内容,弄清在这次课程设计中要完成的需求和功能,既“要解决的问题是什么”,因为如果不知道问题是什么就试图解决这个问题,显然是盲目的。
再结合操作系统的原理进行可行性研究,在这个阶段要回答的关键问题是:
“上个阶段确定的问题是否有行得通的解决办法”。
最后一个阶段是需求分析阶段,准确回答“目标系统必须做什么”,对目标系统提出完整、准确、清晰和具体的要求。
1.1问题定义
题目:
临界区资源模拟
设计要求:
建立三个进程,模拟进入临界区,然后用一个进程进行管理。
设计技术参数:
1)实现UP、DOWN原语
2)产生3个进程,两个进程模拟需要进入临界区的用户进程。
当需要进入临界区时,显示:
“进程x请求进入临界区…”,同时向管理进程提出申请;
申请返回,表示进入了临界区。
在临界区中等待一段随机时间,并显示:
“进程x正在临界区…”;
当时间结束,显示:
“进程x退出临界区…”,同时向管理进程提出退出申请;
当申请返回,显示:
“进程x已退出临界区。
”
3)一进程作为原语的管理进程,接受其他进程的临界区进入请求。
1.2可行性研究
题目要求建立三个进程,模拟进入临界区,然后用一个进程进行管理,其余两个进程模拟进入临界区的用户进程。
在我们的操作系统,通过信号量进行访问等是很常见的保证进程同步的方法。
1.3需求分析
在该阶段明确对目标系统,即临界区资源模拟的完整、准确、清晰和具体的要求。
1)实现UP、DOWN原语
2)产生3个进程,两个进程模拟需要进入临界区的用户进程。
3)一进程作为原语的管理进程,接受其他进程的临界区进入请求。
2.课题总体设计
在总体设计的环节,概括的回答“怎样实现目标”,确定解决问题的策略集目标系统中赢包含的程序,明确实验原理及程序结构,确定开发环境,画出程序流程图,设计程序的体系结构。
2.1实验原理
通过编写,创建两个进程模拟需要进入临界区,另外编写一个进程作为原语的管理进程,其负责两个进程的进入!
接着设置一个临界区,让其进程在其中访问遵循空闲让进、忙则等待、有限等待、让权等待的准则。
当进程和临界区建立好后,临界区的数据传输,受到了系统硬件的支持,不耗费多余的资源;而进程间通信传递,由软件进行控制和实现,需要消耗一定的CPU资源。
从这个意义上讲,临界区更适合频繁和大量的数据传输。
进程信息的传递,自身就带有同步的控制。
当等到信息的时候,进程进入睡眠状态,不再消耗CPU资源。
而共享队列如果不借助其他机制进行同步,接收数据的一方必须进行不断的查询,白白浪费了大量的CPU资源。
2.2开发环境
结合自己所掌握的知识和技能,采用Java语言编写程序。
开发平台:
Windows7,JDK1.6,Eclipse3.2
2.3程序结构
1.进程的状态反映进程执行进程的变化。
这些状态随着进程的执行和外界条件发生变化和转换。
下图给出了有一个基本状态,即就绪状态、执行状态与等待状态之间的转换关系。
图2-1
2.PCB的组织方式
PCB的组织方式将处于同一状态的进程组织在一起。
链表:
同一状态的进程其PCB成一链表,多个状态对应多个不同的链表
各状态的进程形成不同的链表:
就绪链表、阻塞链表
索引表:
同一状态的进程归入一个index表(由index指向PCB),多个状态对应多个不同的index表
各状态的进行形成不同的索引表:
就绪索引表、阻塞索引表
图2-2
3.进程队列
为了实现对进程的管理,系统将所有进程的PCB排成若干个队列,成为进程队列。
4.唤醒原语
当等待队列中的进程所等待的事件发生时,等待该事件的所有进程都将被唤醒。
显然,一个处于阻塞状态的进程不可能自己唤醒自己(为什么?
)唤醒一个进程有两种方法:
一种是由系统进程唤醒。
另一种是由事件发生进程唤醒。
当由系统进程唤醒等待进程时,系统进程统一控制事件的发生并将“事件发生”这一消息通知等待进程。
从而使得该进程因等待事件已发生而进入就绪队列。
等待进程也可由事件发生进唤醒。
由事件发生进程唤醒时,事件发生进程和被唤醒进程之间是合作关系。
因此,唤醒原语既可被系统进程调用,也可被事件发生进程调用。
我们称调用唤醒原语的进程为唤醒进程。
唤醒原语首先将被唤醒进程从相应的等待队列中摘下,将被唤醒进程置为就绪状态之后,送入就绪队列。
在把被唤醒进程送入就绪队列之后,唤醒原语既可以返回原调用程序,也可以转向进程调度,以便让调度程序有机会选择一个合适的进程执行。
2.4程序流程图
图2-3程序流程图
2.5程序的体系结构
1.界面设计
2.临界区及进程管理模块设计
3.临界资源设计
4.设定一个进程作为原语的管理的进程,接受其他进程的临界区进入请求
5.通信快设计,两个进程模拟用户进程进行通信
3.课题详细设计
3.1界面设计代码
//设计界面
importjava.awt.BorderLayout;
importjava.awt.Color;
importjava.awt.Container;
importjava.awt.GridLayout;
importjava.awt.Toolkit;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.FocusEvent;
importjava.awt.event.FocusListener;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
importjavax.swing.JScrollPane;
importjavax.swing.JTextArea;
importjavax.swing.JTextField;
importjavax.swing.ScrollPaneConstants;
importjavax.swing.border.LineBorder;
publicclassMainFrameextendsJFrameimplementsFocusListener{
JTextAreajta=newJTextArea();//多行文本框
staticJTextFieldjtf[]=newJTextField[2];//单行文本框
staticJButtonjb[]=newJButton[2];//按钮
ThreadShowts=newThreadShow();
//界面设计
publicMainFrame(){
super("编程模拟多进程共享临界资源");//题目命名
JLabeljl[]=newJLabel[2];
//初始化单行文本区,并获得焦点
for(inti=0;ijtf[i]=newJTextField();
jtf[i].setText("");
jtf[i].addFocusListener(this);
}
jl[0]=newJLabel("线程1的名称:
");//设置标签名称,显示线程
jl[1]=newJLabel("线程2的名称:
");
jb[0]=newJButton("开始演示");//设置按钮名称,控制程序的开始和结束
jb[1]=newJButton("退出");
Containercont=this.getContentPane();//初始化一个容器
cont.setLayout(newBorderLayout());//设置布局管理器
//面板
JPaneljp1=newJPanel();
JPaneljp2=newJPanel();
jp1.setLayout(newGridLayout(0,1));
//添加文本区
for(inti=0;iJPaneltemp=newJPanel();
temp.add(jl[i]);
temp.add(jtf[i]);
jp1.add(temp);
}
//添加按钮
for(inti=0;ijp2.add(jb[i]);
}
jp1.add(jp2);
jp1.setBorder(newLineBorder(newColor(0,0,0),10));
jp1.setBorder(newLineBorder(newColor(238,238,238),10));
cont.setLayout(newBorderLayout());
cont.add(jp1,BorderLayout.NORTH);
jta.setEnabled(false);//设置控件不可用
JScrollPanejs=newJScrollPane(jta,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);//添加滚动条
jta.setBorder(newLineBorder(newColor(34,57,12),1));
js.setBorder(newLineBorder(newColor(238,238,238),10));
cont.add(js,BorderLayout.CENTER);
this.setSize(300,400);//定义界面大小
this.setDefaultCloseOperation(3);
//设置当前界面显示时相对屏幕的位置
this.setLocation(
Toolkit.getDefaultToolkit().getScreenSize().width/2-175,
Toolkit.getDefaultToolkit().getScreenSize().height/2-200);
this.setResizable(false);//窗口大小不可变
this.setVisible(true);//显示当前窗口
//jb1添加监听器
jb[1].addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEventarg0){
if(ts.tu1!
=null&&ts.tu1.isAlive())ts.tu1.interrupt();
if(ts.tu2!
=null&&ts.tu2.isAlive())ts.tu2.interrupt();
System.exit(0);
}
});
//jb0添加监听器
jb[0].addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEventarg0){
for(inti=0;iMainFrame.jb[0].setEnabled(false);
jta.setText("");
ts.run(jtf[0].getText().trim(),jtf[1].getText().trim(),jta);
}
});
}
publicstaticvoidmain(Stringares[]){
newMainFrame();
}
publicvoidfocusGained(FocusEventarg0){
//当用户点击文本框时,文本框就把当前内容清空
JTextFieldjtf=(JTextField)arg0.getSource();
jtf.setText("");
}
publicvoidfocusLost(FocusEventarg0){
//TODO自动生成方法存根
}
}
3.2临界区及进程管理模块设计代码
importjava.util.Vector;
importjavax.swing.JOptionPane;
/*临界区*/
classThreadManagerimplementsRunnable{/*指向要管理得临界资源*/
ThingSomeobj;
/*记录obj是否已有使用者*/
booleanjud=false;
Vectorvec=newVector();
Stringname;
publicThreadManager(ThingSomets){
obj=ts;
}
publicvoidrun(){
while(vec.size()!
=0){
for(inti=0;iif(!
((Thread)vec.get(i)).isAlive()){//如果线程知行结束
//System.out.println(vec.get(i).getName()+""+vec.get(i).isAlive());
((Thread)vec.get(i)).interrupt();//使被阻塞的线程抛出一个中断异//常,从而使线程提前结束阻塞状态,退出堵塞代码。
vec.remove(i);
}
}
try{
Thread.currentThread().sleep(100);
}catch(InterruptedExceptione){
//TODO自动生成catch块
e.printStackTrace();
}
}
JOptionPane.showMessageDialog(null,"演示完毕","信息",//结束窗口
JOptionPane.INFORMATION_MESSAGE);
for(inti=0;iMainFrame.jtf[i].setText("");
MainFrame.jtf[i].setEditable(true);
}
MainFrame.jb[0].setEnabled(true);//控件可用
}
publicvoidaddThreadUser(ThreadUseruser){
vec.add(user);
}
//进程控制块
publicvoidtake(Threaduser){
System.out.println("进程"+user.getName()+"请求进入临界区.....");
obj.jta.append("进程"+user.getName()+"请求进入临界区.....\n");
//如果jud为true,表示有线程正在使用资源,
//如果jud为false,表示资源没有被使用
while(jud){
try{
System.out.println("进程"+user.getName()+"等待.....");
obj.jta.append("进程"+user.getName()+"等待.....\n");
synchronized(obj){
//进入资源的等待池中,等待被唤醒
obj.wait();
}
}catch(InterruptedExceptione){
//TODO自动生成catch块
//e.printStackTrace();
}
}
System.out.println("进程"+user.getName()+"进入临界区.....");
obj.jta.append("进程"+user.getName()+"进入临界区.....\n");
jud=true;
//使用资源
obj.useing(user);
jud=false;
System.out.println("进程"+user.getName()+"已退出临界区");
obj.jta.append("进程"+user.getName()+"已退出临界区\n");
synchronized(obj){
//把资源等待池中的线程唤醒
obj.notifyAll();
}
}
}
3.3临界资源设计
importjavax.swing.JTextArea;
/*临界资源*/
classThingSome
{
staticJTextAreajta=newJTextArea();
publicThingSome(){}
publicThingSome(JTextAreajta){
this.jta=jta;
}
publicvoiduseing(Threaduser){
System.out.println("进程"+user.getName()+"正在临界区…");
jta.append("进程"+user.getName()+"正在临界区…\n");
try{
/*模拟使用者使用了该资源一段时间*/
Thread.currentThread().sleep(500);
}