10035黄乾操作系统课程设计报告文档格式.docx
《10035黄乾操作系统课程设计报告文档格式.docx》由会员分享,可在线阅读,更多相关《10035黄乾操作系统课程设计报告文档格式.docx(16页珍藏版)》请在冰点文库上搜索。
1.需求分析
(1)分析
本次课题需要用到的知识有多线程编程等知识。
本次涉及到的读者-写者问题采用的是写者优先的方案,写者优先的设计思想是在一个写者到达时如果有正在工作的读者,那么该写者只要等待正在工作的读者完成,而不必等候其后面到来的读者就可以进行写操作。
而且该算法当一个写者在等待时,后到达的读者是在写者之后被挂起,而不是立即允许进入。
为了达到我们的目的,我们在程序中要设置一个专门针对写者的标志位,由这个标志位以及其他条件共同维持进程资源的分配。
(2)描述
编程模拟读者与写者问题,要求显示结果。
①多个进程共享一个文件,其中只读文件的称之为读者,其余只写文件的称为写者。
读者可以同时读,但是写者只能独立写。
②对①修改,使得它对写者优先,即一旦有写者到,后续的读者都必须等待,而无论是否有读者在读文件。
(3)课题描述
本次课程设计的主要内容是模拟读者-写者问题,读者-写者问题时一个经典的进程间同步的问题,计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据,另一些进程则要求修改数据,这时就出现了一个问题,就是进程之间如何分配资源的问题,如何合理的让这些进程使用这些“共同的资源”,避免出现某些进程“霸占”资源,而某些进程长期得不到资源的现象。
其中,进程分配有三种方式:
①写者优先②读者优先③公平竞争。
本次课题是根据“写者优先”的方式解决这个问题的。
2.系统设计
(1)概要设计
该程序算法主要集中解决读者写者对资源分配的问题上。
①本次课程设计使用Java语言来完成,根据题目分析,同一时间,只能有一个读者或写者能够占用资源,所以在某个进程或线程正在占用资源的时候,要对该资源“上锁”,所以在运行程序时,要保证该资源在运行时JVM中只有一个资源实例,即要保证单例。
②在保证单例的情况下,还要配合使用Java的synchronized关键字,来保证多个线程运行时,只能有一个线程占用该对象。
(2)详细设计
读者开始读取:
{
while(当前没有写者){
挂起线程;
}
读者人数+1;
读者读取完毕:
读者人数-1;
if(当前没有读者而且等待写入的人大于1个){
通知其他进程开始分配资源;
写者开始写入:
等待写入者+1;
if(当前有写者或者读者){
finally{
等待写入者-1;
写入者+1;
}
写入者写入完毕:
写者人数-1;
通知其他进程开始分配资源;
流程图如下:
3.系统实现
(1)系统代码
/**
*读者类
*
*@authorZHENGWEI
*@date2015-10-19
*/
publicclassReaderextendsThread{
privateRWOperaterwOperate=newRWOperate();
privateStringreaderName;
/**
*读者类构造方法
*@paramreaderName
publicReader(StringreaderName){
this.readerName=readerName;
*线程方法
publicvoidrun(){
try{
rwOperate.read(this.readerName);
}catch(InterruptedExceptione){
e.printStackTrace();
}
*写者类
publicclassWriterextendsThread{
privateRWOperaterwOperate=newRWOperate();
privateStringwriterName;
*写者类的构造方法
*@paramwriterName
publicWriter(StringwriterName){
this.writerName=writerName;
rwOperate.write(this.writerName);
*读写操作的类
publicclassRWOperate{
privateRWLocklock=RWLock.getInstance();
*读方法
*读者代号
*@throwsInterruptedException
publicvoidread(StringreaderName)throwsInterruptedException{
lock.readLock(readerName);
System.out.println("
读者"
+readerName+"
开始读"
);
Thread.sleep(1000);
}finally{
lock.readUnlock(readerName);
*写方法
*写者代号
publicvoidwrite(StringwriterName)throwsInterruptedException{
lock.writeLock(writerName);
写者"
+writerName+"
开始写"
lock.writeUnlock(writerName);
*控制读写的锁类
publicclassRWLock{
privateintreader=0;
//当前读的人数
privateintwriter=0;
//当前写的人数
privateintwriterWating=0;
//等待写的人数
privatebooleanisWriting=false;
//写操作的标志位
privatevolatilestaticRWLockrwLock;
//使用volatile保证该对象的内部变量的一致性
*私有化构造方法
privateRWLock(){
*使用双重校验锁保证该类为单例
*@return
publicstaticRWLockgetInstance(){
if(rwLock==null){
synchronized(RWLock.class){
if(rwLock==null){
rwLock=newRWLock();
}
}
returnrwLock;
*读,加锁
publicsynchronizedvoidreadLock(StringreaderName)
throwsInterruptedException{
while(writer>
0||writerWating>
0||isWriting){
System.out.println("
正在等待中..."
this.wait();
++reader;
*读,解锁
publicsynchronizedvoidreadUnlock(StringreaderName)
--reader;
读取完毕"
if(reader==0&
&
writerWating>
0){
this.notify();
*写,加锁
publicsynchronizedvoidwriteLock(StringwriterName)
++writerWating;
isWriting=true;
while(writer>
0||reader>
System.out.println("
正在等待..."
this.wait();
writerWating--;
++writer;
*写,解锁
*
publicsynchronizedvoidwriteUnlock(StringwriterName)
isWriting=false;
--writer;
写入完毕"
//要使用notifyAll,不可使用notify,否则可能进入死锁状态
this.notifyAll();
publicclassReaderAndWriter{
publicstaticvoidmain(String[]args){
Writerw1=newWriter("
1"
Writerw2=newWriter("
2"
Readerr1=newReader("
Readerr2=newReader("
Readerr3=newReader("
3"
r1.start();
r2.start();
w1.start();
r3.start();
w2.start();
(2)系统执行过程
①首先在主方法中,创建对应的一定数量的读者和写者,代码中只是做一个示例,实际中的个数是不受限制的。
创建好读者写者后,可以随机调用读者写者的开始方法,由此读者和写者开启线程,进行对应的操作。
②先看读者,读者在主函数中被调用了有参数的构造方法,构造方法的作用主要是传递名称,意在打印出来的时候便于区分,之后主方法中调用开始方法的时候,会调用读者的run方法,run方法是调用了rwOperate类的read方法。
③rwOperate类在初始化的时候,首先要声明一个读写锁的类RWLock。
RWLock类的主要作用就是在代码执行过程中,对临界资源进行加锁。
④RWLock类中分为两大类:
读锁和写锁,读锁和写锁又分为读加锁,读解锁,写加锁,写解锁。
而且要保证RWLock类时单例模式,即在一个JVM中,只有一个该类的实例。
这里采用了synchronized关键字进行双重校验,以达到单例模式,若非单例模式,则可能会导致对临界资源的控制失效。
⑤RWLock类中有reader、writer、writerWating、isWriting四个变量对当前临界资源进行相应的控制。
reader可以有多个,但是writer只能有一个,所以对这4个变量的控制也就成为了程序成功与否的重点。
⑥读加锁,判断若当前有写者,或有正在等待的写者,或当前正在写入,则要一直等待,直到所有写者写入完毕,读者才可以将读者人数加1,执行读方法,否则就要一直在循环中调用wait方法进行挂起等待。
⑦读方法,在此处就是模拟读方法,输出一句话,休眠一秒钟,字实际中可以写入具体的操作方法。
操作完毕后,进行读解锁。
⑧读解锁,将当前读者人数减去1,判断若当前有写者正在等待,则唤醒线程,进行写入操作,否则不采取任何操作。
⑨写者,写者在主函数中被调用了有参数的构造方法,构造方法的作用主要是传递名称,意在打印出来的时候便于区分,之后主方法中调用开始方法的时候,会调用写者的run方法,run方法是调用了rwOperate类的write方法。
⑩rwOperate类在初始化的时候,首先要声明一个读写锁的类RWLock。
⑪写加锁,将当前等待写入的人数加1,isWriting设为true。
如果当前有写者正在写入,或者当前有读者,则需要等待,否则等待读者人数减1,之后执行写方法。
⑫写方法,在此处就是模拟写方法,输出一句话,休眠一秒钟,字实际中可以写入具体的操作方法。
操作完毕后,进行写解锁。
⑬写解锁,isWriting为false,writer减去1,唤醒所有等待的线程,让其重新开始竞争。
执行下一次操作。
4.系统测试
系统测试环境如下,Windows764bit,Tomcat6.0,JRE5.0
测试结果如下:
三、结论(应当准确、完整、明确精练;
也可以在结论或讨论中提出建议、设想、尚待解决问题等。
1、结论
此段程序能够满足我们之前的要求,通过对读者和写者不同的判断方式,达到了写者优先的控制方式,正确的模拟了在操作系统中的情景。
通过对程序中的多线程的控制,模拟并解决了操作系统中的经典问题。
2、感悟
通过这次的课程设计,让我了解了读者-写者问题。
同时让我更好地掌握了多线程编程等知识,以及一些书本上没有的东西,知识是学不完的,要掌握一个正确的学习方法,针对各种不同的问题能有不同的解决方案,这对我以后的学习生涯以及将来步入社会起到很大的帮助。
在这次的课程设计中不仅检验了我所学习的知识,也培养了我如何去把握一件事情,如何去做一件事情,又如何完成一件事情。
在设计过程中,和老师同学们相互探讨,相互学习,相互监督。
学会了合作,学会了运筹帷幄,学会了宽容,学会了理解,也学会了做人与处世。
课程设计是我们专业课程知识综合应用的实践训练,着是我们迈向社会,从事职业
工作前一个必不少的过程。
我今天认真的进行课程设计,学会脚踏实地迈开这一步,就是为明天能稳健地在社会大潮中奔跑打下坚实的基础。
通过此次课程设计,使我更加扎实的掌握了有关操作系统方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。
过而能改,善莫大焉。
在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。
最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。
这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师和同学的指导帮助下,终于游逆而解。
在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!
课程设计诚然是一门专业课,给我很多专业知识以及专业技能上的提升,同时又是一门讲道课,一门辩思课,给了我许多道理,给了我很多思考,
给了我莫大的空间。
同时,设计让我感触很深。
使我对抽象的理论有了具体的认识。
四、参考文献
[1]刘振鹏.操作系统[M].北京:
中国铁道出版社,2007
[2]庞丽萍.操作系统原理[M].北京:
华中科技大学出版社,2008
[3]张丽芬.操作系统原理教程[M].北京:
电子工业出版社,2009
[4]陈向群.现代操作系统[M].北京:
机械工业出版社,2005
[5]任爱华.操作系统实用教程[M].北京:
清华大学出版社,2010
[6]郑扣根.操作系统概念[M].北京:
高等教育出版社,2010
[7]刘任任.算法设计与分析[M].武汉:
武汉理工大学出版社,2003
[8]王晓东.计算机算法设计与分析[M].北京:
电子工业出版社,2007
五、指导教师评语
签名:
年月日
课程设计成绩(五级分制)