资源描述
某某大学
课程设计汇报
课程名称: 操作系统课程设计
设计题目: 读者写者问题
系 别: 计算机系
专 业: 计算机科学和技术
组 别: 第四组
学生姓名: 某某某 学 号:
起止日期:
指导老师:
目 录
1、需求分析 1
1.1 课程设计题目 1
1.2课程任务及要求 1
1.3课程设计思想 1
1.4软硬件运行环境及开发工具 2
2、 概要设计 2
2.1程序步骤图 2
2.2所用原理 3
2.2.1 并发原理 3
2.2.2 互斥操作原理 4
2.2.3 面向对象编程编程原理 4
2.2.4 锁机制原理 5
2.2.5 线程原理 6
2.2.6 读者写者问题通常应用 6
3、 具体设计 6
4、 调试和操作说明 11
5、 课程设计总结和体会 12
6、 致谢 13
7、 参考文件 13
1、需求分析
1.1 课程设计题目
课程设计题目:读者写者问题
1.2课程任务及要求
编写程序实现读者写者算法(读_写互斥,读_读许可,写写互斥)
给出处理方案(包含说明设计实现原理,采取数据结构等)
画出程序基础结构框图和步骤图
分析说明每一部分程序设计思绪
实现源代码
按期提交完整程序代码和可实施程序
依据要求完成课程设计汇报
总结
1.3课程设计思想
读者-写者问题是一个经典并发程序设计问题。有两组并发进程:读者和写者,共享文件F,要求:
(1) 允很多个读者同时对文件实施读操作;
(2) 只许可一个写者对文件实施写操作;
(3) 任何写者在完成写操作之前不许可其它读者或写者工作;
(4) 写者在实施写操作前,应让已经有写者和读者全部退出。
单纯使用信号量不能处理此问题,必需引入计数器readcount对读进程记数。
为了有效处理读者写者问题,需要引进读者-写者锁,允很多名读者同时以只读方法存取有锁保护对象;或一位写者以写方法存取有锁保护对象。当一名或多名读者上锁后,此时形成读锁,写者将不能访问有锁保护对象;当锁被请求者用于写操作时,形成写锁,其它进程读写操作必需等候。
1.4软硬件运行环境及开发工具
本课程设计在windows操作系统下,使用java语言完成。
2、 概要设计
2.1程序步骤图
本系统关键有读者和写者两类对象,所以系统关键针正确是这两类对象操作。
读者类对象步骤图以下:
图2.1 读者类对象
写者类对象步骤图以下:
图2.2 写者类对象
2.2所用原理
2.2.1 并发原理
进程并发是指一组进程实施在时间上重合,所谓时间重合是指一个进程实施第一条指令是在另一个进程实施完最终一条指令之前开始。
并发实质是处理器在多个进程之间多路复用,并发是对有限物理资源强制行使多用户共享,消除计算机部件之间互等现象,提升系统资源利用率。
并发进程可能是无关,也可能是交互。进程交互必需是有控制,不然会出现不正确计算结果。
2.2.2 互斥操作原理
互斥是指若干进程因相互争夺独占型资源而产生竞争制约关系。
并发进程中和共享变量相关程序段称为“临界区”,共享变量所代表资源称为“临界资源”,临界区必需以一个相对于其它进程而言相互排斥方法实施。假如能够确保一个进程在临界区实施时,不让另一个进程进入相同临界区,即各进程对共享变量访问是互斥,那么,就不会引发和时间相关错误。
而为了正确而有效地使用临界资源,共享变量并发进程应遵守临界区调度三个标准:
一次至多有一个进程进入临界区内实施;假如已经有进程在临界区中,试图进入临界区其它进程应等候;进入临界区内进程应在有限时间内退出,方便让等候队列中一个进程进入。总结起来有三句话:互斥使用,有空让进;忙则等候,有限等候;择一而入,算法可行。
2.2.3 面向对象编程编程原理
面向对象是一个新兴程序设计方法,或说它是一个新程序设计范型,其基础思想是使用对象,类,继承,封装,消息等基础概念来进行程序设计。
它是从现实世界中客观存在事物(即对象)出发来结构软件系统,并在系统结构中尽可能利用人类自然思维方法,强调直接以问题域(现实世界)中事物为中心来思索问题,认识问题,并依据这些事物本质特点,把她们抽象地表示为系统中对象,作为系统基础组成单位(而不是用部分和现实世界中事物相关比较远,而且没有对应关系其它概念来结构系统)。这能够使系统直接地映射问题域,保持问题域中事物及其相互关系原来面貌。
本课程设计中包含了两个对象,所以用面向对象语言来编程是适合。我们这次用到了Java语言。
2.2.4 锁机制原理
为了处理读者和写者之间同时互斥问题,在本课程设计中要用到Java中锁机制,这么会给编程带来很大方便。
多线程同时实现最终依靠锁机制。我们能够想象某一共享资源是一间屋子,每个人全部是一个线程。当A期望进入房间时,她必需取得门锁,一旦A取得门锁,她进去后就立即将门锁上,于是B,C,D...就不得不在门外等候,直到A释放锁出来后,B,C,D...中某一人抢到了该锁(具体抢法依靠于JVM实现,能够先到先得,也能够随机挑选),然后进屋又将门锁上。这么,任一时刻最多有一人在屋内(使用共享资源)。 Java语言规范内置了对多线程支持。对于Java程序来说,每一个对象实例全部有一把“锁”,一旦某个线程取得了该锁,别线程假如期望取得该锁,只能等候这个线程释放锁以后。取得锁方法只有一个,就是synchronized关键字。
1. 用锁操作原语实现互斥
为处理进程互斥进人临界区问题,可为每类临界区设置一把锁,该锁有打开和关闭两种状态,进程实施临界区程序操作按下列步骤进行:
①关锁。先检验锁状态,如为关闭状态,则等候其打开;如已打开了,则将其关闭,继续实施步骤②操作。
②实施临界区程序。
③开锁。将锁打开,退出临界区。
2.WAIT,NOTIFY,NOTIFYALL操作原语
信号量初值能够由系统依据资源情况和使用需要来确定。在初始条件下信号量指针项能够置为0,表示队列为空。信号量在使用过程中它值是可变,但只能由WAIT,SIGNAL操作来改变。设信号量为S,对SWAIT操作记为WAIT(S),对它SIGNAL操作记为SIGNAL(S)。
WAIT(S):次序实施以下两个动作:
1)信号量值减1,即S=S-1;
2)假如S≥0,则该进程继续实施;
假如 S<0,则把该进程状态置为阻塞态,把对应WAITCB连人该信号量队列末尾,并放弃处理机,进行等候(直至其它进程在S上实施SIGNAL操作,把它释放出来为止)。
SIGNAL(S):次序实施以下两个动作
2.2.5 线程原理
线程是进程中实体,一个进程能够拥有多个线程,一个线程必需有一个父进程。线程不拥有系统资源,只有运行必需部分数据结构;它和父进程其它线程共享该进程所拥有全部资源。线程能够创建和撤消线程,从而实现程序并发实施。通常,线程含有就绪、阻塞和运行三种基础状态。
2.2.6 读者写者问题通常应用
读者写者是经典并发程序设计问题,它方法能够普遍用于多线程同时互斥问题,对于共享资源出现问题做出了很好处理,使得事物并发效率更高,类似问题还有生产者-消费者问题,剪发师问题等等。
3、 具体设计
此次课程设计采取是java语言编写,所以要用到类,包含读者类和写者类,它们全部是继承线程Thread类,在主程序中创建类对象(读者对象和写者对象),用线程来实现并发
读者类对象和写者类对象公共属性包含:
private static final int NAP_TIME=5;
private int readerCount;
private int writerCount;
private boolean dbReading;
private boolean dbWriting;
经过NAP_TIME调整线程随机休息时间
经过readercount和writercount来统计读者和写者线程个数
经过dbreading和dbwriting来判定读者和写者状态,
其中读者是靠判定writercount>0来实现读写互斥,同时许可读读同时;
而写者是靠判定dbreading=true||dbwriting=true来实现读写互斥和写写互斥。
读写等候是随机,利用是math.random()函数
程序代码以下:
class Database
{/*读者写者公用资源Database类*/
private static final int NAP_TIME=5;
private int readerCount; /*统计目前读者个数*/
private int writerCount; /*统计目前写者个数*/
private boolean dbReading; /*显示是否有读者在读*/
private boolean dbWriting; /*显示是否有写者在写*/
public Database() {/*结构函数*/
super();
readerCount=0;
writerCount=0;
dbReading=false;
dbWriting=false;
// TODO Auto-generated constructor stub
}
public static void napping()
{
int sleepTime=(int)(NAP_TIME * Math.random());
try{
Thread.sleep(sleepTime*1000);
}
catch(Exception e){
e.printStackTrace();
}
}
public synchronized int startRead(){
while(writerCount>0){ /*假如有写者在写,那么读者进行等候*/
try{
System.out.println("reader is waiting");
wait();
}
catch(Exception e){
System.out.println(e.toString());
e.printStackTrace();
}
}
++readerCount;
if(readerCount==1){ /*假如有读者读,则设置读状态为true*/
dbReading=true;
}
return readerCount;
}
public synchronized int endReading(){
--readerCount;
if(readerCount==0){ /*假如没有有读者读,则设置读状态为false*/
dbReading=false;
}
notifyAll(); /*释放全部等候线程*/
System.out.println("one reader is done reading. Count="+readerCount);
return readerCount;
}
public synchronized void startWriting(){
++writerCount;
while(dbReading==true||dbWriting==true)
{/*假如有读者在读或有写者在写,那么写者进行等候*/
try{
System.out.println("Writer is waiting");
wait();
}
catch(Exception e){
System.out.println(e.toString());
}
}
dbWriting =true; /*有写者在写,则设置写状态为true*/
}
public synchronized void endWriting(){
--writerCount;
/*因为每次只有一个写者在写,所以结束写操作后写者个数一定为0*/
dbWriting=false; /*没有写者写,则设置写状态为false*/
System.out.println("one writer is done writing. Count="+writerCount);
notifyAll(); /*释放全部等候线程*/
}
}
class Reader extends Thread
{ /*建立读者类*/
private Database server;
private int readerNum;
public Reader(int r,Database db) {
super();
readerNum=r;
server=db;
}
public void run(){
int c;
while(true){
System.out.println("reader "+readerNum+" is sleeping");
Database.napping();
System.out.println("reader "+readerNum+" wants to read");
c=server.startRead();
System.out.println("reader "+readerNum+" is reading. Count="+c);
Database.napping();
c=server.endReading();
System.out.println("It is reader "+readerNum+" who has done reading according to count="+c);
}
}
}
class Writer extends Thread
{ /*建立写者类*/
private Database server;
private int writerNum;
public Writer(int w,Database db) {
super();
writerNum=w;
server=db;
}
public void run(){
while(true){
System.out.println("Writer "+writerNum+" is sleeping");
Database.napping();
System.out.println("Writer "+writerNum+" wants to write");
server.startWriting();
System.out.println("Writer "+writerNum+" is writing");
Database.napping();
server.endWriting();
System.out.println("It is Writer "+writerNum+" who has done writing .");
}
}
}
public class DatabaseServer {
public DatabaseServer() {
super();
}
public static void main(String[] args) {
Database db=new Database();
/*建立四个读者对象和两个写者对象*/
Reader r1=new Reader(1,db);
Reader r2=new Reader(2,db);
Reader r3=new Reader(3,db);
Reader r4=new Reader(4,db);
Writer w1=new Writer(1,db);
Writer w2=new Writer(2,db);
r1.start();
r2.start();
r3.start();
w1.start();
r4.start();
w2.start();
}
}
4、 调试和操作说明
因为读写等候是随机所以可能出现多中情况,读写次序可能会不一样,以下是多个不一样运行结果:
图4.1 读者写者结果一
上图中结果说明:根据读者1、读者2、读者3、写者1、读者4、写者2……次序进入,最终实施结果按写者1、写者2、读者2、4、3、1……次序进行。
图4.2 读者写者结果二
上图中结果说明:根据读者1、读者3、读者2、写者1……次序进入,最终实施结果按读者3、读者1、写者2……次序进行。
5、 课程设计总结和体会
经过集体努力,这次课程设计基础上能够完成功效了,读_写互斥,读_读许可,写写互斥能够实现了,不过还存在部分不足地方,比如不能够实现读者优先或写者优先,可能出现长时间等候情况,在这次课程设计后,我们会继续努力将功效完善。
这次我们收获就是知道了使用Java这么面向对象语言来实现线程同时互斥问题,知道了Java中锁机制,这对以后编程有很大帮助,同时也深入加深了对操作系统这类问题了解。
6、 致谢
感谢一学期来老师给我们教导,让我们对操作系统有了整体了解,这对我们以后学习有很大帮助,对于这次课程设计,老师也给了我们充足支持和了解,是您对我们指导帮助我们能够顺利完成这次课程设计。
7、 参考文件
[1] 费翔林,骆斌. 操作系统教程(第4版)[M]. 北京: 高等教育出版社, .
[2] 李尊朝,苏军.Java语言程序设计(第二版)[M].中国铁道出版社,.
指导老师评语:
指导老师署名: 年 月 日
成绩评定
项 目
权重
成绩
1、设计过程中出勤、学习态度等方面
0.1
2、设计技术水平
0.4
3、安全程度及可操作程度
0.2
4、设计汇报书写及图纸规范程度
0.3
总 成 绩
教研室审核意见:
教研室主任签字: 年 月 日
教学院(系)审核意见:
主任签字: 年 月 日
展开阅读全文