操作系统课程设计报告.docx
- 文档编号:27135018
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:41
- 大小:143.52KB
操作系统课程设计报告.docx
《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(41页珍藏版)》请在冰豆网上搜索。
操作系统课程设计报告
操作系统课程设计实验报告
学院:
计算机科学与技术学院
班级:
13级计算机基地班
姓名:
王**
学号:
201300130101
日期:
2015/6/14
Project1
.
1.1.1问题描述
(5%,5lines)ImplementKThread.join().Notethatanotherthreaddoesnothavetocalljoin(),butifitiscalled,itmustbecalledonlyonce.Theresultofcallingjoin()asecondtimeonthesamethreadisundefined,evenifthesecondcallerisadifferentthreadthanthefirstcaller.Athreadmustfinishexecutingnormallywhetherornotitisjoined.
实现join()方法,注意,其他线程没必要调用join()方法,但是如果它被调用的话,也只能被调用一次。
join()方法不允许被调用第二次,即使第二次调用的线程和第一次调用的线程是不同的。
无论有没有被join(),一个进程都必须能正常结束。
1.1.2原理和方法
join()方法的功能是让直行该方法的程序先于当前线程执行完毕,即当线程B执行A.join()时,将B放入A的等待队列,直到A完成时,唤醒在等待队列中的所有线程,因此需要实现join()方法和修改finish()方法。
1.1.3实现代码
publicvoidjoin(){
Lib.debug(dbgThread,"Joiningtothread:
"+toString());
Lib.assertTrue(this!
=currentThread);
Lib.assertTrue(join_counter==0);
join_count++;//用于计数挂在当前线程的个数
booleanstatus=Machine.interrupt().disable();//关中断
//如果当前线程未结束,则sleep
if(this.status!
=statusFinished){
waitQueue.waitForAccess(KThread.currentThread());currentThread.sleep();
}
Machine.interrupt().restore(status);//开中断
}
publicstaticvoidfinish(){
Lib.debug(dbgThread,"Finishingthread:
"+currentThread.toString());
Machine.interrupt().disable();Machine.autoGrader().finishingCurrentThread();Lib.assertTrue(toBeDestroyed==null);
toBeDestroyed=currentThread;
currentThread.status=statusFinished;
//唤醒挂起在当前结束线程的线程
KThreadthread=currentThread().waitQueue.nextThread();
if(thread!
=null)
{
thread.ready();
}
sleep();
}
1.1.4重点难点
这个题目的重点就是理解join()方法具体是要实现什么功能,如果不理解join()的功能,则实现肯定是做不到的,因为join()功能的实现不能仅仅在join()中实现,finish()方法中的代码也必须得加入才可以实现一个完整的join()功能。
为了能够充分理解join()的功能,我特地在查看了JDK中join的实现,并使用join()方法写了几个小程序,充分理解了join()后再做这个认为就清晰明了很多了。
.
1.2.1问题描述
(5%,20lines)Implementconditionvariablesdirectly,byusinginterruptenableanddisabletoprovideatomicity.Wehaveprovidedasampleimplementationthatusessemaphores;yourjobistoprovideanequivalentimplementationwithoutdirectlyusingsemaphores(youmayofcoursestilluselocks,eventhoughtheyindirectlyusesemaphores).Onceyouaredone,youwillhavetwoalternativeimplementationsthatprovidetheexactsamefunctionality.Yoursecondimplementationofconditionvariablesmustresideinclassnachos.threads.Condition2.
通过使用开关中断提供原子性来直接实现条件变量,我们利用信号量提供了一个简单的实现方式,你的工作就是不直接使用信号量提供相同的实现(你或许使用锁,即使它们也间接的使用了信号量)。
一旦你实现了,你将会有两种可选择的实现方式来提供相同的功能。
你的第二种条件变量的实现必须放在Condition2中
1.2.2原理和方法
sleep():
调用这个方法的线程将自己挂起到等待队列,阻塞自己的同时将自己拥有的锁交出去,之后等待锁的分配。
交出去的锁,会被外面的线程竞争。
拿到锁的线程再次拥有权限接受检验。
wake():
方法是把条件变量中的线程移出,放入就绪队列。
wakeAll():
方法是将条件变量中的所有线程移出,移入就绪队列,将所有等待队列里的线程唤醒。
1.2.3实现代码
publicvoidsleep(){
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanstatus=Machine.interrupt().disable();//关中断
conditionLock.release();
waitqueue.waitForAccess(KThread.currentThread());
KThread.currentThread().sleep();//当前线程sleep
conditionLock.acquire();//处于就绪队列的线程获取锁,然后进行操作
Machine.interrupt().restore(status);//开中断
}
publicvoidwake(){
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanstatus=Machine.interrupt().disable();//关中断
//线程移出等待队列移入就绪队列
KThreadthread=waitqueue.nextThread();
if(!
(thread==null))
thread.ready();
Machine.interrupt().restore(status);//开中断
}
publicvoidwakeAll(){
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanstatus=Machine.interrupt().disable();//关中断
//将条件变量中的所有线程移出,移入就绪队列
KThreadthread=waitqueue.nextThread();
while(!
(thread==null))
{thread.ready();
thread=waitqueue.nextThread();
}
Machine.interrupt().restore(status);//开中断
}
1.2.4重点难点
实现这个功能的难点在于理解互斥锁的工作原理,互斥锁是用来实现进程的同步和互斥的结构,多个线程并发执行的时候,只有当某个线程拿到了互斥锁才能运行,其他线程不能运行。
因此使用互斥锁可以很轻松地实现该要求的功能。
.
1.3.1问题描述
(10%,40lines)CompletetheimplementationoftheAlarmclass,byimplementingthewaitUntil(longx)method.AthreadcallswaitUntiltosuspenditsownexecutionuntiltimehasadvancedtoatleastnow+x.Thisisusefulforthreadsthatoperateinreal-time,forexample,forblinkingthecursoroncepersecond.Thereisnorequirementthatthreadsstartrunningimmediatelyafterwakingup;justputthemonthereadyqueueinthetimerinterrupthandleraftertheyhavewaitedforatleasttherightamountoftime.DonotforkanyadditionalthreadstoimplementwaitUntil();youneedonlymodifywaitUntil()andthetimerinterrupthandler.waitUntilisnotlimitedtoonethread;anynumberofthreadsmaycallitandbesuspendedatanyonetime.
实现Alarm类,线程调用waitUntil方法之后会终止,直到传入的时间之后才可以执行。
线程没必要在等待的时间之后立刻执行,只是把它放入ready队列,等待分配cpu。
可以使用一个线程队列,但是不能产生额外的线程。
1.3.2原理和方法
waitUnti():
方法使用了一个队列可以存放线程以及唤醒时间,这个队列以时间为序的有序队列。
每次调用时,把当前线程和唤醒时间加入队列,等待唤醒。
timerInterrup():
方法在每一次timer产生时间中断时遍历队列,检查队列中的时间状态,当线程到了等待的时间就把线程从队列中取出放入就绪队列。
KThreadWakeTime类是一个内部类用于联系线程和唤醒时间
1.3.3实现代码
publicvoidwaitUntil(longx){
booleanstatus=Machine.interrupt().disable();//关中断
longwake_time=Machine.timer().getTime()+x;
KThreadWakeTimekthreadwaketime=newKThreadWakeTime(
KThread.currentThread(),wake_time);
//linkedlist用于存放唤醒时间
intsize=linkedlist.size();
if(size==0)
linkedlist.add(kthreadwaketime);
else
for(inti=0;i if(wake_time linkedlist.add(i,kthreadwaketime); break; } if(i==size-1 &&wake_time>=linkedlist.get(i).getWakeTime()) linkedlist.add(i+1,kthreadwaketime); } KThread.currentThread().sleep(); Machine.interrupt().restore(status);//开中断 } publicvoidtimerInterrupt(){ booleanstatus=Machine.interrupt().disable();//关中断 longcurrent_time=Machine.timer().getTime(); intsize=linkedlist.size(); //遍历队列,当线程到了等待的时间就把线程从队列中取出放入就 if(size==0) break; else for(inti=0;i if(current_time else{ KThreadthread=linkedlist.get(i).getThread(); thread.ready(); linkedlist.remove(i); size--; i=0; current_time=Machine.timer().getTime(); } } KThread.currentThread().yield(); Machine.interrupt().restore(status);//开中断 } publicclassKThreadWakeTime{ privateKThreadthread=null; privatelongwake_time=0; publicKThreadWakeTime(KThreadthread,longwake_time){ this.thread=thread; this.wake_time=wake_time; } //获得线程 publicKThreadgetThread(){ returnthread; } //获得唤醒时间 publiclonggetWakeTime(){ returnwake_time; } } 1.3.4重点难点 本题目的重点在于利用timer产生的中断来控制线程,让线程可以等待指定的时间开始。 必须将需要等待的线程存入到队列中,并且在每个时间中断时遍历该队列查看是否有时间满足要求的线程可以启动。 . 1.4.1问题描述 (20%,40lines)Implementsynchronoussendandreceiveofonewordmessages(alsoknownasAda-stylerendezvous),usingconditionvariables(don'tusesemaphores! ).ImplementtheCommunicatorclasswithoperations,voidspeak(intword)andintlisten(). speak()atomicallywaitsuntillisten()iscalledonthesameCommunicatorobject,andthentransfersthewordovertolisten().Oncethetransferismade,bothcanreturn.Similarly,listen()waitsuntilspeak()iscalled,atwhichpointthetransferismade,andbothcanreturn(listen()returnstheword).Thismeansthatneitherthreadmayreturnfromlisten()orspeak()untilthewordtransferhasbeenmade.YoursolutionshouldworkeveniftherearemultiplespeakersandlistenersforthesameCommunicator(note: thisisequivalenttoazero-lengthboundedbuffer;sincethebufferhasnoroom,theproducerandconsumermustinteractdirectly,requiringthattheywaitforoneanother).Eachcommunicatorshouldonlyuseexactlyonelock.Ifyou'reusingmorethanonelock,you'remakingthingstoocomplicated. 使用条件变量(不能使用semaphores! )实现一个字长信息的同步发送和接收。 使用voidspeak(intword)和intlisten()函数来实现Communicator类的通讯工作。 Speak()函数具有原子性,在相同的Communicator类中等待listen()函数被调用,然后将此字传输给listen()函数。 一旦传送完毕,两个函数都返回(listen函数返回此字)。 1.4.2原理和方法 speak(): 先获得锁,然后进行判断,如果没有听者等待,就要把说者放入队列然后睡眠。 如果有听者等待,就要唤醒一个听者,然后传递消息,最后释放锁。 listen(): 先获得锁,然后进行判断,如果没有说者等待,就要把听者放入队列然后睡眠。 如果有说者等待,就要唤醒一个说者,然后传递消息,最后释放锁。 1.4.3实现代码 publicCommunicator(){ lock=newLock(); queue=newLinkedList speaker=newCondition2(lock); listener=newCondition2(lock); word=0; speakercount=0; listenercount=0; } publicvoidspeak(intword){ booleanintStatus=Machine.interrupt().disable(); lock.acquire();//获得锁 //判断有没有听者等待 if(listenercount==0) { //如果没有听者等待,就要把说者放入队列然后睡眠 speakercount++; queue.offer(word); speaker.sleep(); listener.wake(); speakercount--; } else { //如果有听者等待,就要唤醒一个听者 queue.offer(word); listener.wake(); } lock.release();//最后释放锁 Machine.interrupt().restore(intStatus); return; } publicintlisten(){ booleanintStatus=Machine.interrupt().disable(); lock.acquire();//获得锁 //判断有没有说者等待 if(speakercount! =0) { //如果有说者等待,就要唤醒一个说者 speaker.wake(); listener.sleep(); } else { //如果没有说者等待,就要把说者放入队列然后睡眠 listenercount++; listener.sleep(); listenercount--; } lock.release();//最后释放锁 Machine.interrupt().restore(intStatus); returnqueue.poll(); } 1.4.4重点难点 本问题的实现需要理解好Communicator正确实现后的功能,即对一个Communicator类的对象c,线程A先调用c.speaker(x)发送一个字后被挂起,直到另一线程B调用c.listen()收到这个字x后,A和B同时返回.类似地,线程B先调用c.listen(x)后被挂起,直到另一线程B调用c.speaker(x)发送一个字后,A和B同时返回.同时需要注意在一个Communicator上有多个spaker和listener的情形.此时的speaker和listener只能是一对一的,即一个speaker只能将数据发送到一个listener,一个listener也只能接收来自一个spekaer的数据,其余的speakers和listeners都需要等待。 理解了Communicator类的功能需求后,就容易实现了。 . 1.5.1问题描述 (35%,125lines)ImplementpriorityschedulinginNachosbycompletingthePrioritySchedulerclass.Priorityschedulingisakeybuildingblockinreal-timesystems.Notethatinordertouseyourpriorityscheduler,youwillneedtochangealineinnachos.confthatspecifiesthesch
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 报告