/ Lesson  

Nachos课设要求翻译 Ⅰ

虽然不是看不懂,但密密麻麻的英语小字实在是辣眼睛,还是翻译一下,顺便逼自己加快进度别懒了。。。_(:з」∠)_

Phase 1 为内核进程建立线程系统

Tasks:

1.(5%,5行,5/100)实现KThread.join()
注意join方法只能被调用一次,即使是不同的线程也禁止二次调用。
2.(5%,20行,10/100)直接实现条件变量,通过开关中断来提供原子性。
已经用信号量实现了一个例子,你的任务是不用信号量来完成等价的实现。
可以用锁,即使锁也是间接使用了信号量。
你完成的版本在类nachos.threads.Condition2中。
3.(10%,40行,20/100)实现waitUntil(long x)方法来完成Alarm类。
调用这个函数可以挂起自己本身的执行,直到时间now+x。
(这对实时操作的线程很有用。举例来说,每秒光标闪烁一次。)
线程被唤醒后不需要立即开始执行,只要在它们等待一定时间后,将它们放在定时器中断处理程序的就绪队列中即可。
不要fork多余的线程来实现waitUntil,你只需要修改waitUnti()和定时器中断处理程序。
waitUntil不只限于一个线程,任何数量的线程可以同时调用并被挂起。
4.(20%,40/100)实现同步收发一个词的消息。用条件变量,不要用信号量!
flag:不看代码下边讲解愣是一个字没看懂。。。喵的,待会看完源码回来翻译
5.(35%,75/100)通过补全PriorityScheduler类实现优先级调度。
实时调度是建造实时系统block的关键。
为了使用你的优先级调度,你需要更改nachos.conf中的一行来指明要用的调度程序类。ThreadedKernel.scheduler初始值为nachos.threads.RoundRobinScheduler。当你想用优先级调度来运行Nachos时,你需要将它改成nachos.threads.PriorityScheduler。
必须实现方法:getPriority(),getEffectivePriority()与setPriority().
可选实现方法:increasePriority()与decreasePriority()
在选择哪个线程出列时,调度程序总应该选择效率最高的线程。如果有许多相同高优先级的线程在等待,调度程序要选等待最久的那个。

- 优先级转化问题:如果一个高优先级线程需要等待一个低优先级线程,并且另一个高优先级线程已经在就绪列表中,那么这个高优先级线程将永远不能得到CPU,因为低优先级线程将不会获得任何CPU时间。
- 一个部分的修正方案是当等待的线程持有锁时,将它的优先级donate给低优先级线程。
- 实现优先级调度目的是让它在可能的时候捐出自己的优先级。确保实现在考虑了自己收到的所有donations后返回线程优先级的Scheduler.getEffectivePriority()
- 当解决优先级捐赠问题时,你将会发现你可以很容易的计算一个线程的有效优先级,但是计算会占很长时间。为了在设计project的这一方面时得到满分,你应该通过缓存有效优先级并只在可能变化时重新计算线程的有效优先级来加速。
- 注意在实现这一部分时不要破坏抽象的barriers——类Lock不需要修改。优先级捐赠应该通过创建一个实现了此功能的ThreadQueue的子类来完成,并且当使用已经存在的Semaphore与Condition类时应该正常运行。优先级同样应该通过线程join来捐赠。
- 优先级捐赠实现细节:
    ①一个线程的有效优先级通过计算捐赠者与接受者优先级的最大值确定。如果优先级4的线程A捐赠个线程B优先级2,那么线程B的有效优先级现在是4.注意线程A的优先级仍然是4.一个捐赠给其他线程优先级的线程不会损失自己的优先级。因此,“优先级继承”这个术语比“优先级捐赠”更合适。
    ②优先级捐赠是传递性的。如果线程A捐赠给线程B,随后线程B捐赠给线程C,线程B将会捐赠它从A处获得后的新的有效优先级给C。

6.(25%,150行,100/100)对这个问题,条件变量是最有效的同步方法。一些夏威夷大人和小孩想从Oahu去Molokai。但不幸的是,他们只有一艘最多可以同时载两个孩子或者一个大人的船(一个大人一个小孩是不行的),只要有人划,船可以回到Oahu

- 假定至少有两个孩子,安排一个可以将所有人从Oahu送到Molokai的方案。
- 方法Boat.begin()应该为每个人创建一个进程。我们要将Boat.begin()作为父进程。你的机制不能依赖于事先知道有多少个孩子或大人,尽管你可以随意尝试在线程间定义这些。(也就是说,你不可以在方法*begin()*中传递参数大人与孩子,但如果你想的话,你可以使每个线程增加共享变量来尝试确定这个值)
- 为了展示这趟旅程是正确的同步了的,每次有人穿越河道时都要恰当调用BoatGrader方法。当一个孩子驾船从Oahu到Molokai时,调用ChildRowToMolokai。当一个孩子作为乘客从O到M时,调用ChildRideToMolokai。确保当两个人过河时,先调用...RideTo...方法,再调用...RowTo...方法。
- 你的解决方案不能有忙等,并且最终必须能结束。