一题目project1:实现nachos操作系统的project1中的join()方法,condition2 类,Alarm类,Communicator类,PriorityScheduler类和Boat类project2:实现nachos操作系统的project2中的creat open read write close unlink 文件系统调用,修改UserProcess.readVirtualMemory和UserProcess.writeVirtualMemory使操作系统能够运行多用户程序,实现exec join exit系统调用,实现LotteryScheduler类二实验目的熟悉nachos操作系统,深入理解操作系统内核了解用户程序的加载过程以及多用户进程的内存分配机制三实验要求完成nachos,提交设计文档和你的代码四实验说明,程序代码及测试结果Project1:1 join()要求实现join()方法,注意,其他线程没必要调用join函数,但是如果它被调用的话,也只能被调用一次。
join()方法第二次调用的结果是不被定义的,即使第二次调用的线程和第一次调用的线程是不同的。
无论有没有被join,一个进程都能够正常结束(a)设计思想当线程B执行A.join()时,将B放入A的等待队列,直到A完成时,唤醒在等待队列中的所有线程,因此需要实现join()方法和修改finish方法(b)源代码public void join(){Lib.debug(dbgThread, "Joining to thread:" + toString());Lib.assertTrue(this!=currentThread);Lib.assertTrue(join_counter == 0);join_counter++;boolean status=Machine.interrupt().disable();if (this.status != statusFinished) {waitQueue.waitForAccess(KThread.currentThread());currentThread.sleep();}Machine.interrupt().restore(s tatus);}public static void finish(){Lib.debug(dbgThread, "Finishing thread:" +currentThread.toString());Machine.interrupt().disable();Machine.autoGrader().finishingCurrentThread();Lib.assertTrue(toBeDestroyed == null);toBeDestroyed= currentThread;currentThread.status = statusFinished;KThread thread= currentThread().waitQueue.nextThread();if (thread!= null){thread.ready();}sleep();}(c)程序截图线程1每次执行打出执行的次数,每次执行过后放弃cpu,线程2 打出successful,线程2 执行thread1.join().通过截图可以看出代码正确2 Condition2通过使用开关中断提供原子性来直接实现条件变量,我们利用信号量提供了一个简单的实现方式,你的工作就是不直接使用信号量提供相同的实现(你或许使用锁,即使它们也间接的使用了信号量)。
一旦你实现了,你将会有两种可选择的实现方式来提供相同的功能。
你的第二种条件变量的实现必须放在Condition2 中(a)设计思想Condition2 是对使用该条件变量的线程进行管理,所以要把在这个条件变量上等待的进程储存起来,因此可以使用一个队列。
sleep()方法是把等待该条件变量的线程阻塞,放入等待队列,直到执行了wake()并且获得cpu 才能继续执行,执行步骤:关中断,释放锁,把线程放入等待队列,获得锁,开中断。
wake()方法是把条件变量中的线程移出,放入就绪队列。
执行步骤:关中断,线程移出等待队列移入就绪队列,开中断wakeAll()方法是将条件变量中的所有线程移出,移入就绪队列(b)源代码public void sleep(){Lib.assertTrue(conditionLock.isHeldByCurrentThread());boolean status=Machine.interrupt().disable();conditionLock.release();waitqueue.waitForAccess(KThread.currentThread());KThread. currentThread().sleep();conditionLock.acquire();Machine.interrupt().restore(s tatus);}public void wake(){Lib.assertTrue(conditionLock.isHeldByCurrentThread());boolean status=Machine.interrupt().disable();KThread thread=waitqueue.nextThread();if (!(thread==null))thread.ready();Machine.interrupt().restore(s tatus);}public void wakeAll(){Lib.assertTrue(conditionLock.isHeldByCurrentThread());boolean status=Machine.interrupt().disable();KThread thread=waitqueue.nextThread();while(!(thread==null)){ thread.ready();thread=waitqueue.nextThread();}Machine.interrupt().restore(s tatus);}(c)程序截图线程1线程 2 分别请求锁和条件变量,然后释放锁和条件变量,图中可以看出代码正确3 Alarm类实现Alarm 类,线程调用waitUntil方法之后会终止,直到传入的时间之后才可以执行。
线程没必要在等待的时间之后立刻执行,只是把它放入ready队列,等待分配cpu。
可以使用一个线程队列,但是不能产生额外的线程。
(a)设计思想waitUntil()方法使用了一个队列可以存放线程以及唤醒时间,这个队列以时间为序的有序队列。
每次调用时,把当前线程和唤醒时间加入队列,等待唤醒。
timerInterrupt()方法在每一次timer 产生时间中断时遍历队列,检查队列中的时间状态,当线程到了等待的时间就把线程从队列中取出放入就绪队列。
KThreadWakeTime类是一个内部类用于联系线程和唤醒时间(b)源代码public void waitUntil(long x) {boolean status=Machine.interrupt().disable();long waketime= Machine.timer().getTime() + x;KThreadWakeTime kthreadwaketime=newKThreadWakeTime(KThread.currentThread(),waketime);int size=linkedlist.size();if (size== 0)linkedlist.add(kthreadwaketime);elsefor (int i = 0; i <size; i++){if (waketime< linkedlist.get(i).getWakeTime()){ linkedlist.add(i, kthreadwaketime);break;}if (i==size-1&& waketime>= linkedlist.get(i).getWakeTime())linkedlist.add(i + 1, kthreadwaketime);}KThread. currentThread().sleep();Machine.interrupt().restore(s tatus);}public void timerInterrupt(){boolean status=Machine.interrupt().disable();long currenttime= Machine.timer().getTime();int size=linkedlist.size();if (size== 0);elsefor (int i = 0; i <size; i++){if (currenttime< linkedlist.get(i).getWakeTime());else {KThread thread= linkedlist.get(i).getThread();thread.ready();linkedlist.remove(i);size--;i = 0;currenttime= Machine.timer().getTime();}}KThread.currentThread ().yield();Machine.interrupt().restore(s tatus);}public class KThreadWakeTime{private KThread thread= null;private long waketime=0;public KThreadWakeTime(KThread thread,long waketime){this.thread = thread;this.waketime =waketime;}public KThread getThread(){return thread;}public long getWakeTime(){return waketime;}}(c)程序截图创建一个线程在70时中止,等待500后唤醒。
图中可以看出代码正确4 Communicator利用条件变量编写发送和接收一个消息来实现Communicator类的speak ()和listen()方法。