Nachos操作系统:Pro1_5:实现优先级调度

Nachos操作系统:Pro1_5:实现优先级调度


问题描述

  1. Change a line in nachos.conf that specifies the scheduler class to use.
  2. You must implement the methods getPriority(), getEffectivePriority(), and setPriority().
  3. In choosing which thread to dequeue, the scheduler should always choose a thread of the highest effective priority. If multiple threads with the same highest priority are waiting, the scheduler should choose the one that has been waiting in the queue the longest.
  4. A partial fix for this problem is to have the waiting thread donate its priority to the low priority thread while it is holding the lock.
  5. Be sure to implement Scheduler.getEffectivePriority(), which returns the priority of a thread after taking into account all the donations it is receiving.
  6. The Lock class does not need to be modified.

问题重述

  • 通过完成实现 PriorityScheduler 优先级调度策略。所有的调度程序都是继承自 Scheduler 类,所以必须实getPriority(),getEffectivePriority()和setPriority()方法。

分析

Nachos 系统已经提供了一个简单的轮转调度器,采用简单的 FIFO 队列进行调度。优先级调度的传统算法如下: 每个线程拥有一个优先级(在 Nachos中, 优先级是一个 0 到 7 之间的整数, 默认为 1)。在线程调度时, 调度程序选择一个拥有最高优先级的处于就绪状态的线程运行。

解决优先级问题的关键就是优先级反转,当一个高优先级的线程等待一个低优先级的线程时,高优先级的线程就必须把自己的有效优先级捐献给低优先级的线程,让低优先级的线程提高优先级可以尽快执行。解决这个问题的关键就是计算有效优先级,但是计算时间不能太长,所以在改变优先级的时候在计算比较合适。优先级在捐献之后不会丢失。优先级可以不断传递下去。

所以首先要在线程对象中完成对线程优先级修改的函数的实现,方便后面设置修改线程优先级完成试验的测试过程。

关键函数

函数描述
getPrioritythread - the thread to get the priority of.
setPrioritythread - the thread to set the priority of. priority - the new priority.
getEffectivePrioritythread - the thread to get the effective priority of.

getEffectivePriority:

计算有效优先级时,遍历等待队列中所用线程的有效优先级,找出最大的优先级。首先要在 PriorityQueue 类下创建个装有KThread 的LinkedList,即等待队列 waitQueue,声明一个 effectivePriority,遍历waitQueue,找出 priority 最大的那个 KThread,将它的 priority 赋给effectivePriority,然后返回即可。

实现

在 PriorityScheduler 类的内部类ThreadState 类里有 priority 这属性,所以实现 getPriority(),setPriority(),increasePriority(),decreasePriority()时直接对 priority 进行返回,重新赋值,修改 priority 的值。(注意getPriority(), setPriority()函数内部是先调用内部类 ThreadState 类的同名函数,然后在这些同名函数里对 priority修改。

getEffectivePriority()

该方法是实现优先级继承功能的关键。先说这个方法的功能实现。我们通过该方法获取一个线程的有效优先级(即其所属的等待队列中所有线程中最高的一个优先级数值),这个优先级将用于赋给该线程,确保该线程的运行顺利进行以避免饥饿现象。在该方法的实现过程中,首先我们遍历waitQueue(其中保存了该线程的所属的所有PriorityQueue类型的等待队列),在其中选取一个最大的优先级赋在一个局部变量中暂时保存下来。就像之前提到的,waitQueue是一个保存PriorityQueue对象的迭代器,这意味着在我的实现中有些不属于PriorityQueue对象的等待队列无法通过对waitQueue的便利得到。可以通过把这样的队列单拉出来进行遍历,选出其中最大的一个返回作为该线程的优先级即完成了该方法的任务。

public int getEffectivePriority() {
        // implement  on 2016/10/29 by CAO dove
        int maxEffective =this.priority;

        if(dirty){
            //迭代器遍历,加快遍历速度
            for(Iterator<ThreadQueue> it =myResource.iterator();it.hasNext();){
                PriorityQueue pg = (PriorityQueue)(it.next()); 
                //遍历myResource(其中保存了该线程的所属的所有PriorityQueue类型的等待队列),在其中选取一个最大的优先级赋在一个局部变量中暂时保存下来。
                int effective = pg.getEffectivePriority();
                if (maxEffective < effective) {
                    maxEffective=effective;
                }
            }
        }

测试结果如下:
这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值