山东大学操作系统个人报告-软件八班杨环Word文档格式.docx
- 文档编号:13089610
- 上传时间:2022-10-04
- 格式:DOCX
- 页数:20
- 大小:106.92KB
山东大学操作系统个人报告-软件八班杨环Word文档格式.docx
《山东大学操作系统个人报告-软件八班杨环Word文档格式.docx》由会员分享,可在线阅读,更多相关《山东大学操作系统个人报告-软件八班杨环Word文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
TASK1.1
[任务]
实现KThread.join()
当前线程a在运行,执行b.join(),则a阻塞,直到线程b结束,a继续执行。
几个重要的方法
禁止中断机制的实现
Interrupt类有一个boolean型变量enabled,其值true时,表示允许中断,false不允许中断。
一般方法不希望执行过程中被中断就在方法
开始处添加booleanintStatus=Machine.interrupt().disable();
结束处添加Machine.interrupt().restore(intStatus);
关中断disable()只有一句returnsetStatus(false)设置interrupt状态为false,并且以前的状态保存在intstatus,开中断处restore(intStatus)就是将enabled值设为intStatus;
这样就实现了开关中断的过程。
setStatus(booleanstatus)方法还模拟了系统内的时间“前进”,
当interrupt的状态从不可行变为可行,即关中断到开中断,模仿时间前进:
tick(true)。
KThread.sleep()当前线程没有结束,就将其状态设为”阻塞”,通过调度器类
从就绪队列中选择下一个执行的进程,选择过程又与调度器种类与策略有关。
Lib.assertTrue(s) Lib里面是一些写好了的函数库,
Lib.assertTrue如果括号内语句为false,则抛出一个异常.
抽象类threadqueue有waitForAccess(KThread thread)和acquire(KThread
thread)两个抽象方法,threadqueue我是这样理解的:
一个线程队列等待着某个资源,所以每个临界资源可以用当前等待着的线程队列来指代,waitForAccess(t)说明t也加入到该资源的等待队列了,acquire(t)则表示t已经得到这个资源了。
抽象类Scheduler里有个方法newThreadQueue(boolean
transferPriority)该方法构造了一个线程队列,调度器在线程等待队列选择下一个可获得资源访问权限时需要使用一个参数,姑且称为“优先级”,优先级高的可得到资源,这会导致饥饿,如cpu也是一个资源,就绪队列等待
cpu资源,如果ABC三个线程优先级分别是321,B等待着C所占有的一个资源,C只有运行结束才释放这个B等代着的资源,C当前拥有cpu,当根据普通优先级调度方法它无法获得CPU,进而B也无法执行,所以就约定当前获得
CPU线程优先级可以直接设为不小于等待队列中最大的优先级,以便于优先级小的线程快点结束释放其拥有的资源
[代码]
在KThread.java中:
privateThreadQueuejoinQueue=null;
每个kthread对象都有自己的joinQueue,由由对本线程调用join方法的其他线程对象构成,可“捐赠”优先级
privatebooleanJoined=false;
布尔形变量joined,判断本线程是否被其他线程调用过join方法,完善finish()方法时会用到
publicbooleanIsAlive(){
if(this.status==statusNew||status==statusReady||status==statusRunning||status==statusBlocked)
returntrue;
elsereturnfalse;
}
一个简单的判断线程是否结束的方法,Kthread有五种状态,只要状态不为
finished,就返回true
publicvoidjoin(){
Lib.debug(dbgThread,"
Joiningtothread:
"
+toString());
Lib.assertTrue(this!
=currentThread);
if(this.status==statusFinished)return;
booleanintStatus=Machine.interrupt().disable();
//关中
断
this.hasBeenJoined=true;
//设置join标志,在finish方法中使
用
if(this.joinQueue==null){
this.joinQueue=ThreadedKernel.scheduler.newThreadQueue(true);
this.joinQueue.acquire(this);
//新建一个可转让优先级的线程队列
joinqueue,调用join方法的进程直接拥有该队列的最高优先级
this.joinQueue.waitForAccess(KThread.currentThread());
//currentThread()等待在队列上KThread.sleep();
Machine.interrupt().restore(intStatus);
publicstaticvoidfinish(){Machine.autoGrader().finishingCurrentThread();
if(currentThread.Joined){
currentThread.joinQueue.nextThread().ready();
//currentThread结束前检查Joined标志,有等待线程的就选择一个加入就绪队列
Lib.assertTrue(toBeDestroyed==null);
toBeDestroyed=currentThread;
currentThread.status=statusFinished;
sleep();
//执行就绪队列下个线程
在join类测试代码里
创建AThread和Bthread两个线程,AThread循环打印“AThread循环第..次”语句,Bthread开始打印“B_thread就绪”语句,
中间执行AThread。
Join()方法,最后打印“B_thread执行结束”语句。
根据结果可以验证基本实现了join()方法
TASK1.2
用允许/屏蔽中断的方法实现条件变量
Condition类中已有利用信号量实现的条件变量,我们需要实现不依靠信号变量的实现,
Condition最重要的部分是对Lock类的使用,
Lock可被视为线程运行必需的“资源”,拥有lock资源的线程才能访问一些临界资源,即不能被多线程同时访问或修改的资源,lock对象拥有一个ThreadQueuewaitQueue,且优先级转让标志为true,这意味着获得lock的线程不会因为优先级问题失去该
lock。
Lock.release()方法让当前拥有锁的线程放弃锁,通过lockHolder =
waitQueue.nextThread()来实现。
Lock.acquire()方法要求得到锁,若要求时锁没被其他线程拥有,则调用
acquire()方法的线程直接得到锁,否则将调用acquire()方法的线程加到
lock对象的waitQueue中等待。
Condition2类也有一个waitQueue,用来存放等待在条件变量上的线程,
sleep方法的核心是在conditionLock.release();
KThread.sleep();
//
conditionLock.acquire();
过程中,线程调用
Condition2.sleep()方法后,失去锁,阻塞在conditionlock这个资源上,要acquire()才能结束sleep()方法。
condition.Wake()只能被拥有
conditionLock资源的线程执行,故可实现一个线程等待"
条件变量的条件成立"
而挂起;
另一个线程使"
条件成立"
;
互斥锁的使用为了防止竞争,与条件变量结合在一起。
publicclassCondition2{
publicCondition2(LockconditionLock){
this.conditionLock=conditionLock;
waitQueue=newLinkedList<
KThread>
();
publicvoidsleep(){Lib.assertTrue(conditionLock.isHeldByCurrentThread());
booleanintStatus=Machine.interrupt().disable();
//关中断waitQueue.add(KThread.currentThread());
//当前线程被添加到条件变量的等待队列上
conditionLock.release();
//释放锁
//线程状态设为阻塞
//要求锁,这是线程阻塞的原因
Machine.interrupt().restore(intStatus);
//开中断
publicvoidwake(){Lib.assertTrue(conditionLock.isHeldByCurrentThread());
//只能被拥有conditionLock资源的线程执行
//关中断waitQueue.remove().ready();
//直接将waitQueue里的线程移出并将其状态设为ready
publicvoidwakeAll(){Lib.assertTrue(conditionLock.isHeldByCurrentThread());
while(!
waitQueue.isEmpty())
wake();
//利用while循环将waitqueue里所有线程“唤醒”
privateLockconditionLock;
privateLinkedList<
waitQueue;
在Condition2测试方法里
创建共有条件变量c2test,一个临界资源count和三个线程,thread1,thread2,thread3,初始化三个线程后thread1,thread2调用c2test.sleep()后开始“睡眠”,thread3调用c2test.wakeAll()唤醒所有线程,thread1,thead
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 山东大学 操作系统 个人 报告 软件 八班杨环