山东大学计算机学院操作系统实验报告.docx
- 文档编号:3090631
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:35
- 大小:31.34KB
山东大学计算机学院操作系统实验报告.docx
《山东大学计算机学院操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《山东大学计算机学院操作系统实验报告.docx(35页珍藏版)》请在冰豆网上搜索。
山东大学计算机学院操作系统实验报告
山东大学计算机学院操作系统实验报告
操作系统课程设计报告
学院:
计算机科学与技术学院
专业:
计算机科学与技术
班级:
20**级*班
姓名:
***
学号:
20**********
一实验平台
开发语言:
Java
开发工具:
EclipseLuna
操作系统:
Ubuntu14.04
二Project1建立线程系统
Task1.1实现KThread.join()
1.要求
实现ImplementKThread.join()函数。
注意:
其它的线程不必调用join函数,但是如果它被调用的话,也只能被调用一次。
对join函数第二次调用的执行结果是不被定义的(即使第二次调用的线程与第一次调用的线程不同)。
2.分析
Join函数的作用即为等待某线程运行完毕.当前线程(唯一一个正在运行的线程)A调用另一个线程(处于就绪状态)B的join函数时(A和B在Nachos中均为KThread类型对象),A被挂起,直到B运行结束后,join函数返回,A才能继续运行。
3.方案
原KThread的join()中的Lib.assertTrue(this!
=currentThread)已经实现线程只能调用一次join()方法,根据要求,在调用join()方法时,让当前运行线程休眠,并将当前运行的线程加入到一个阻塞队列中。
在线程结束时,finish()函数循环唤醒所有被阻塞的线程。
4.实现代码
publicvoidjoin()
{
Lib.debug(dbgThread,"Joiningtothread:
"+toString());
Lib.assertTrue(this!
=currentThread);
booleanintStatus=Machine.interrupt().disable();
if(status!
=statusFinished)
{
waitForJoin.waitForAccess(currentThread);
KThread.sleep();
}
}
publicstaticvoidfinish()
{
Lib.debug(dbgThread,"Finishingthread:
"+currentThread.toString());
Machine.interrupt().disable();
Machine.autoGrader().finishingCurrentThread();
Lib.assertTrue(toBeDestroyed==null);
toBeDestroyed=currentThread;
currentThread.status=statusFinished;
KThreadwaitThread;
while((waitThread=currentThread.waitForJoin.nextThread())!
=null)
{
waitThread.ready();
}
sleep();
}
Task1.2利用中断提供原子性,直接实现条件变量
1.要求
通过利用中断有效和无效所提供的原子性实现条件变量。
我们已经提供类似的例子用例实现信号量。
你要按此提供类似的条件变量的实现,不能直接利用信号量来实现(你可以使用lock,虽然它间接地调用了信号量)。
在你完成时要提供条件变量的两种实现方法。
你的第二种条件变量实现要放在nachos.threads.Condition2中。
2.分析
threads.Lock类提供了锁以保证互斥.在临界代码区的两端执行Lock.acquire()和Lock.release()即可保证同时只有一个线程访问临界代码区.条件变量建立在锁之上,由threads.Condition实现,它是用来保证同步的工具.每一个条件变量拥有一个锁变量(该锁变量亦可被执行acquire和release操作,多个条件变量可共享同一个锁变量).当处于临界区内的拥有某锁L的当前线程对与锁L联系的条件变量执行sleep操作时,该线程失去锁L并被挂起.下一个等待锁L的线程获得锁L(这个过程由调度程序完成)并进入临界区.当拥有锁L的临界区内的当前线程对与锁L联系的条件变量执行wake操作时(通常调用wake之后紧接着就是Lock.release),等待在该条件变量上的之多一个被挂起的线程(由调用sleep引起)被重新唤醒并设置为就绪状态.若执行wakeall操作,则等待在该条件变量上的所有被挂起的线程都被唤醒.
3.方案
condition.sleep采用waiter.P()实现休眠(waitor是一个信号量)并将waitor放入信号量队列,在我们的实现中改成用KThread.sleep()实现休眠并将当前线程放入线程队列,并在sleep函数开始/结尾处屏蔽/允许中断以保证原子性。
condition.wake中从等待信号量队列中取出信号量并对其进行V操作实现唤醒,在我们的实现中改成从线程队列中取出线程用KThread.ready()实现唤醒(同样要在wake函数开始/结尾处屏蔽/允许中断)。
wakeall函数的实现依赖于wake().只需不断地wake直到队列为空为止.
4.实现代码
privateThreadQueuewaitQueue=
ThreadedKernel.scheduler.newThreadQueue(false);
privatebooleanhasWaiter=false;
publicvoidsleep()
{
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanintStatus=Machine.interrupt().disable();
waitQueue.waitForAccess(KThread.currentThread());
hasWaiter=true;
conditionLock.release();
KThread.sleep();
conditionLock.acquire();
Machine.interrupt().restore(intStatus);
}
publicvoidwake()
{
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanintStatus=Machine.interrupt().disable();
KThreadthread=waitQueue.nextThread();
if(thread!
=null)
thread.ready();
else
hasWaiter=false;
Machine.interrupt().restore(intStatus);
}
publicvoidwakeAll()
{
Lib.assertTrue(conditionLock.isHeldByCurrentThread());
while(hasWaiter)
wake();
}
Task1.3实现waitUntil
1.要求
通过实现waitUntil(intx)方法来完成Alarm类。
2.分析
一个线程通过调用waitUntil函数来挂起它自己,直到now+x后才被唤醒。
在实时操作中,对线程是非常有用的,例如实现光标每秒的闪烁。
这里并不要求线程被唤醒后马上执行它,只是在它等待了指定时间后将它。
放入等待队列中。
不要通过产生任何附加的线程来实现waitUntil函数,你仅需要修改waitUntil函数和时间中断处理程序。
waitUntil函数并不仅限于一个线程使用,在任意时间,任意多的线程可以调用它来阻塞自己。
3.方案
于Alarm类有关的是machine.Timer类.它在大约每500个时钟滴答使调用回调函数(由Timer.setInterruptHandler函数设置).因此,Alarm类的构造函数中首先要设置该回调函数Alarm.timerInterrupt().
为了实现waitUntil,需要在Alarm类中实现一个内部类Waiter,保存等待的线程及其唤醒时间.在调用waitUntil(x)函数时,首先得到关于该线程的信息:
(线程:
当前线程,唤醒时间:
当前时间+x),然后构造新的Waiter对象,并调用sleep操作使当前线程挂起.在时钟回调函数中(大约每500个时钟间隔调用一次)则依次检查队列中的每个对象。
如果唤醒时间大于当前时间,则将该对象移出队列并执行wake操作将相应线程唤醒。
4.实现代码
classWaiter
{
Waiter(longwakeTime,KThreadthread)
{
this.wakeTime=wakeTime;
this.thread=thread;
}
privatelongwakeTime;
privateKThreadthread;
}
publicvoidwaitUntil(longx)
{
booleanintStatus=Machine.interrupt().disable();
longwakeTime=Machine.timer().getTime()+x;
Waiterwaiter=newWaiter(wakeTime,KThread.currentThread());
waitlist.add(waiter);
System.out.println(KThread.currentThread().getName()
+"线程休眠,时间为:
"+Machine.timer().getTime()+",应该在
"+wakeTime+"醒来.");
KThread.sleep();
Machine.interrupt().restore(intStatus);
}
publicvoidtimerInterrupt()
{
Waiterwaiter;
for(inti=0;i { waiter=waitlist.remove(); if(waiter.wakeTime<=Machine.timer().getTime()) { System.out.println("唤醒线程: "+waiter.thread.getName()+", 时间为: "+Machine.timer().getTime()); waiter.thread.ready();//线程进入就绪状态 } else waitlist.add(waiter); } KThread.currentThread().yield(); } privateLinkedList Task1.4用条件变量,不使用信号量,实现同步发送接收消息,speak,listen 1.要求 使用条件变量来实现一个字长信息的发送和接收同步。 使用voidspeak(intword)和
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 山东大学 计算机 学院 操作系统 实验 报告