基于nachos系统开发的课设作业 ——Project 1 .5

来源:互联网 发布:c语言迷宫算法基本思路 编辑:程序博客网 时间:2024/06/16 14:19

基于nachos系统开发的课设作业 ——Project 1 的第五问:

题目要求先是完成PriorityScheduler类在Nachos中实现优先级调度。首先在这种调度下,每次调度程序从就绪队列中应该选择优先级最高的那个。此处会出现一种需要我们解决的问题:优先级反转——持有锁的线程的优先级低于就绪队列中的其他线程,则我们将最高优先级暂时性地赋予给之,低优先级的lockholder变成高优先级线程(暂时性),在代码中我们除了priority属性,特设有EffectivePriority一属性,在优先级反转过程中用到该变量。

接下来是实现过程:
首先实现基本的优先级调度:分析PriorityScheduler类,发现其中又包含了两个内部类:
1)PriorityQueue,其注释为——根据优先级将线程分类。我们用一个大根堆来存储所有的线程及其优先级,每次其堆顶是优先级最高的线程,我们将将KTread对象与其相应的优先级(EffectivePriority)加入大根堆中,根据优先级大小排序。该类主要需实现的方法有nextThread()、pickNextThread()。
2):ThreadState——保存一个线程和它的优先级、EffectivePriority、waitQueue。主要需要实现的方法:getEffectivePriority()、setPriority(int priority)、waitForAccess(PriorityQueue waitQueue)、acquire()。
逐一实现:此处对一些较为复杂的实现方法进行说明:ThreadState中的setPriority方法:当我们设置一个线程的优先级时,如果该线程原先的优先级小于重新设置的,则需要更改EffectivePriority,此时大根堆需要刷新一遍。并且如果此时的锁具有拥有者且其优先级低于新设置值,说明在堆中(即就绪队列)存在比lockholder高优先级的线程,要对lockholder进行优先级反转。waitForAccess(PriorityQueue waitQueue)方法:获得就绪队列,向其加入线程,当就绪队列满足优先级反转的条件进行优先级反转。当调用本类中的acquire()方法,说明调用该方法的线程拥有锁。
PriorityQueue中nextThread()方法是获得最大优先级的线程并将其设置成锁的拥有者(lockholder)。
此外重点说明getThreadState(KThread thread)方法:返回包含参数线程的ThreadState对象。
代码基本实现后简单介绍一下程序整个逻辑。由于是通过锁Lock来完成整个线程的调度,查看Lock类:
这里写图片描述
同样的release方法:从等待锁的队列中选择一个线程,唤醒它。(等价于给一个线程锁)
测试程序及结果说明:
这里写图片描述
这里写图片描述
结果说明:
开始主线程执行,获取到锁,此时主线程优先级最低,为1。进行yield()后,调度程序开始选择线程执行:注意此时main线程的优先级低但由于其拥有锁,进行了优先级反转并执行。主线程执行并释放锁,此时从就绪队列中找到优先级最大的线程,给其锁并执行,所以先执行th2(优先级为5).打印出主线程的EffectivePriority,会发现它变成了5。

2 0
原创粉丝点击