操作系统课程设计报告.docx
《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(23页珍藏版)》请在冰点文库上搜索。
操作系统课程设计报告
操作系统课程设计报告
Nachosproject1
院系:
姓名:
姓名:
姓名:
时间:
目录
操作系统课程设计报告1
一、题目:
3
二、实验目的:
3
三、实验内容:
3
3.1、实验内容join():
3
3.2、实验内容condition2():
3
3.3、实验内容waitUntil():
3
3.4、实验内容speak().、listen():
3
3.5、实验内容priorityscheduler:
4
四、程序代码及测试结果4
4.1、join():
4
4.1.1、join():
(线程队列实现)4
4.1.1.1、join()的设计思想:
4
4.1.1.2、join()的源程序:
5
4.1.1.3、join()的测试用例及结果:
5
4.1.2、join():
(信号量实现)6
4.1.2.1、join()的设计思想:
6
4.1.2.2、join()的源程序:
6
4.1.2.3、join()的测试用例及结果:
7
4.2、condition2():
7
4.2.1、condition2()的编程思想:
7
4.2.2、condition2()的源程序:
7
4.2.3、condition2()的测试用例及结果:
8
4.3、waitUntil():
9
4.3.1、waitUntil()的设计思想:
9
4.3.2、waitUntil()源程序:
9
4.3.3、waitUntil()的测试用例及结果:
10
4.4、speak(int)、listen():
11
4.4.1、speak(int)、listen()的设计思想:
11
4.4.2、speak(int)、listen()的源程序:
11
4.4.3、speak(int)、listen()的测试用例及结果:
12
4.5、:
priorityScheduler13
4.5.1、priorityScheduler的设计思想:
13
4.5.2、priorityScheduler的源程序:
13
4.5.3、priorityScheduler的测试用例及结果:
13
五、总结13
一、题目:
实现Nachos操作系统project1中的join(),condition2()、waitUntil()、speak(intword)和listen()函数以及priorityScheduler类。
二、实验目的:
熟悉nachos操作系统,深入理解操作系统内核。
三、实验要求:
完成nachosproject1,提交设计文档和你的代码(包括测试用例)。
四、实验说明、程序代码及测试结果
4.1、join():
要求:
实现ImplementKThread.join()函数。
注意:
其它的线程不必调用join函数,但是如果它被调用的话,也只能被调用一次。
对join函数第二次调用的执行结果是不被定义的(即使第二次调用的线程与第一次调用的线程不同)。
4.1.1、join():
(线程队列实现)
4.1.1.1、join()的设计思想:
当A线程调用B.join()时,A线程阻塞,直到B线程完成。
在join()函数中,在A不为完成态时,将A放到阻塞队列中,并执行阻塞函数。
在finish()函数中,循环唤醒所有被阻塞的线程。
4.1.1.2、join()的源程序:
publicvoidjoin(){
Lib.debug(dbgThread,"Joiningtothread:
"+toString());
Lib.assertTrue(this!
=currentThread);
if(this.status!
=statusFinished)//如果当前进程不是完成态
{
booleanintstatus=Machine.interrupt().disable();
blockQueue.waitForAccess(currentThread);//并把该线程放到阻塞队列中
KThread.sleep();//使该进程休眠
Machine.interrupt().restore(intstatus);
}
}
publicstaticvoidfinish(){
Lib.debug(dbgThread,"Finishingthread:
"currentThread.toString());
Machine.interrupt().disable();
Machine.autoGrader().finishingCurrentThread();
Lib.assertTrue(toBeDestroyed==null);
toBeDestroyed=currentThread;
currentThread.status=statusFinished;
KThreadnextThread=currentThread.blockQueue.nextThread();
while(nextThread!
=null)
{nextThread.ready();
nextThread=currentThread.blockQueue.nextThread();
}
sleep();
}
4.1.1.3、join()的测试用例及结果:
图1.1join()函数测试结果
4.1.2、join():
(信号量实现)
4.1.2.1、join()的设计思想:
在KThread中,我们主要完成了对join函数及finish函数的完善与扩充。
join函数是完成对多个进程需调用同一个进程之间的互斥问题。
为保证每次只有一个进程调用该进程,而且还得保证当第一个调用该进程的进程结束后可以将其它的阻塞进程得于唤醒,因此这需要一个链表来完成该进程的信号量的管理。
join函数中如果调用的进程已经完成则返回,如果未完成,则将定义一个信号量,并将该信号量加入到信号量链表中,并对waiter进行P操作。
相应的在finish函数中得对信号量链表中完成对信号量进程执行V操作,并从信号量链表中移除一个信号量记录。
4.1.2.1、join()的源程序:
publicvoidjoin(){
Lib.debug(dbgThread,"Joiningtothread:
"+toString());
Lib.assertTrue(this!
=currentThread);
if(this.status!
=statusFinished)
{
booleanintstatus=Machine.interrupt().disable();
blockQueue.waitForAccess(currentThread);
KThread.sleep();
Machine.interrupt().restore(intstatus);}
}
publicstaticvoidfinish(){
Lib.debug(dbgThread,"Finishingthread:
"currentThread.toString());
Machine.interrupt().disable();
Machine.autoGrader().finishingCurrentThread();
Lib.assertTrue(toBeDestroyed==null);
toBeDestroyed=currentThread;
currentThread.status=statusFinished;
KThreadnextThread=currentThread.blockQueue.nextThread();
while(nextThread!
=null)
{nextThread.ready();
nextThread=currentThread.blockQueue.nextThread();
}
sleep();
}
4.1.2.3、join()的测试用例及结果:
图1.2join()函数测试结果
4.2、condition2():
要求:
通过利用中断有效和无效所提供的原子性实现条件变量。
我们已经提供类似的例子用例实现信号量。
你要按此提供类似的条件变量的实现,不能直接利用信号量来实现(你可以使用lock,虽然它间接地调用了信号量)。
在你完成时要提供条件变量的两种实现方法。
你的第二种条件变量实现要放在nachos.threads.Condition2中。
4.2.1、condition2()的编程思想:
Condition2的作用是实现对需要使用该条件资源的进程的管理,因此需要一个等待队列将在该条件资源上阻塞的进程存储起来,所以我们定义了一个ThreadQueue类的对象waitQueue。
sleep函数功能是将需要使用该条件资源下的当前进程阻塞,并将当前进程加入到等待队列中。
因此实现该函数的步骤如下:
首先执行关中断操作,然后再释放当前进程所加的锁,目的是为了能将当前进程加入到waitQueue中,然后将当前进程转为阻塞状态,再调用acquire函数来获取锁,最后再执行开中断操作。
wake函数的功能是将在该条件资源上阻塞的进程队列中取一个进程对其进行唤醒操作。
因此实现该函数的步骤如下:
首先执行关中断操作,然后调用nextThread函数从等待队列中取第一个进程,如果无等待该条件资源的进程,则执行开中断操作,跳出该函数,否则就将该进程进行唤醒操作,最近执行开中断操作。
wakeAll函数的功能是将在该条件资源上阻塞的进程都唤醒,因此可通过在while循环中调用wake函数来实现。
但是前提是该当前进程得已经加锁,因此得通过调用Lib.asserTrue(conditionLock.isHeldByCurrentTread)函数来确保该条件成立。
4.2.2、condition2()的源程序:
packagenachos.threads;
importnachos.machine.*;
publicclassCondition2
{
publicCondition2(LockconditionLock){
this.conditionLock=conditionLock;
waitQueue=ThreadedKernel.scheduler.newThreadQueue(false);
}
publicvoidsleep(){
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanintStatus=Machine.interrupt().disable();//关中断
conditionLock.release();//释放当前进程所加的锁
waitQueue.waitForAccess(KThread.currentThread());//将当前的进程加入到等待队列中
KThread.currentThread().sleep();//把当前的进程转为阻塞状态
conditionLock.acquire();//获取锁
Machine.interrupt().restore(intStatus);//开中断
}
publicvoidwake(){
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanintStatus=Machine.interrupt().disable();//关中断
KThreadthread=waitQueue.nextThread();//从等待队列中取一个线程
if(thread==null)//如果线程为空,则开中断
{
Machine.interrupt().restore(intStatus);
return;
}
thread.ready();//否则使这个线程转为就绪状态
Machine.interrupt().restore(intStatus);}
publicvoidwakeAll(){
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
while(waitQueue.!
=null)
{wake();}
privateLockconditionLock;
privatestaticThreadQueuewaitQueue=null;
}
4.2.3、condition2()的测试用例及结果:
图2condition2()函数测试结果
4.3、waitUntil():
要求:
通过实现waitUntil(intx)方法来完成Alarm类。
一个线程通过调用waitUntil函数来挂起它自己,直到now+x后才被唤醒。
在实时操作中,对线程是非常有用的,例如实现光标每秒的闪烁。
这里并不要求线程被唤醒后马上执行它,只是在它等待了指定时间后将它。
放入等待队列中。
不要通过产生任何附加的线程来实现waitUntil函数,你仅需要修改waitUntil函数和时间中断处理程序。
waitUntil函数并不仅限于一个线程使用,在任意时间,任意多的线程可以调用它来阻塞自己。
4.3.1、waitUntil()的设计思想:
Alarm的作用是实现可对多个进程进行阻塞,并在规定的时间将进程唤醒,因此要存储多个进程的进程名及其唤醒时间,因此我们定义了一个ThreadTime类来存储单个进程的信息,属性分别为该进程名与其唤醒时间。
为了可存储多个进程的信息,并且对多个进程按唤醒时间进行排序,因此使用了TreeSet的对象Threadset来存储多个进程的信息并在ThreadTime类中实现了Comparable接口中的CompareTo函数。
waitUntil函数是进程可调用的函数,在该函数中需将各进程的进程名及唤醒时间保存起来。
因此该函数的实现步骤如下:
首先关中断,然后将创建一个ThreadTime类的对象来存储当前进程的信息,并加入到Threadset中,然后再开中断。
timerInterrupt函数是实现将阻塞队列中的进程在其唤醒时间将其唤醒。
为了实现能够对阻塞队列中的进程进行循环判断,因此需创建Iterator的一个对象,然后再利用Iterator的hasNext来对阻塞队列中的进程进行循环判断,如果该进程的唤醒时间大于当前时间,则对下一个进程进行判断,否则就将该进程唤醒,然后从阻塞队列中将其移除,再对下一个进程进行判断,最后将当前进程由运行状态转换成就绪状态,运行下一个进程。
4.3.2、waitUntil()源程序:
packagenachos.threads;
importnachos.machine.*;
importjava.util.*;
publicclassAlarm{
publicAlarm(){
Machine.timer().setInterruptHandler(newRunnable(){
publicvoidrun(){timerInterrupt();}
});
}
//实现将阻塞队列中的进程在其唤醒时间将其唤醒
publicvoidtimerInterrupt()
{
IteratorThreadIterator=Threadset.iterator();while(ThreadIterator.hasNext())
{
ThreadTimethreadtime=(ThreadTime)ThreadIterator.next();
if(threadtime.getwakeTime()>Machine.timer().getTime())//如果该进程的唤醒时间大于当前时间
break;//则对下一个进程进行判断
threadtime.getThread().ready();//将该进程唤醒
ThreadIterator.remove();//从阻塞队列中把它删除
}
KThread.currentThread().yield();
}
publicvoidwaitUntil(longx){
booleanintStatus=Machine.interrupt().disable();//关中断
longwakeTime=Machine.timer().getTime()+x;
ThreadTimethreadtime=newThreadTime();//创建一个ThreadTime类对象。
来储存进程当前的信息
threadtime.setThread(KThread.currentThread());
threadtime.setwakeTime(wakeTime);
Threadset.add(threadtime);//加入到Threadset中
KThread.currentThread().sleep();//当前进程睡眠
Machine.interrupt().restore(intStatus);//关中断
}
publicclassThreadTimeimplementsComparable
{
privateKThreadthread;
privatelongwaketime;
publicKThreadgetThread()
{
returnthread;
}
publicvoidsetThread(KThreadthread)
{
this.thread=thread;
}
publiclonggetwakeTime()
{
returnwaketime;
}
publicvoidsetwakeTime(longwaketime)
{
this.waketime=waketime;
}
publicintcompareTo(Objectp)
{
longtime=((ThreadTime)p).getwakeTime();
if(this.getwakeTime()