Nachos java版学习(一)

    最近,操作系统课程设计使用伯克利大学的Nachos做为实验平台,老师也照搬伯克利的Project要求,开始我们的操作系统课程设计。

    结合自己的学习过程和课设要求,我觉得对Nachos的学习首先应该从KThread.java入手,首先应该看明白这个类的所有函数的意思。

     这个主要是为第一个proj,实现join()函数做准备。 Join()方法的含义:当前线程a在运行,执行b.join(),则a阻塞,直到线程b结束,a继续执行。

     具体的要求有:Join函数的作用即为等待某线程运行完毕。当前线程 (唯一一个正在运行的线程) A调用另一个线程 (处于就绪状态) B的join函数时 (A 和 B 在Nachos中均为KThread类型对象),A被挂起,直到B运行结束后, join函数返回,A才能继续运行。注意在一个KThread对象上只能调用一次join,且当前线程不能对自身调用join。Waits for this thread to finish. If this thread is already finished, return immediately. This method must only be called once; the second call is not guaranteed to return. This thread must not be the current thread.

    

 1 public void join() {
 2 
 3         Lib.debug(dbgThread, "Joining to thread: " + toString());
 4         // 等待另外一个线程结束的这个线程不能是线程自己
 5         Lib.assertTrue(this != currentThread);
 6 
 7         if (this.status == statusFinished)
 8             return;
 9 
10         boolean intStatus = Machine.interrupt().disable();
11 
12         if (joinQueue == null) {
13             joinQueue = ThreadedKernel.scheduler.newThreadQueue(true);
14             // Notify this thread queue that a thread has received access,without going through request() and nextThread()
15             joinQueue.acquire(this);
17         }
18         // Notify this thread queue that the specified thread is waiting for
19         // access
20         joinQueue.waitForAccess(currentThread);
21         KThread.sleep();
22         Machine.interrupt().restore(intStatus);
23     }

 

      为此,我设置了一个KThread的队列joinQueue,当B调用join函数时,将正在执行的A线程放入joinQueue,只有在B执行完后,在finish()里面会将队列中的A线程状态变为ready,从而继续执行A线程,具体finish()实现的代码如下:

 1 public static void finish() {
 2         Lib.debug(dbgThread, "Finishing thread: " + currentThread.toString());
 3 
 4         Machine.interrupt().disable();
 5 
 6         Machine.autoGrader().finishingCurrentThread();
 7 
 8         Lib.assertTrue(toBeDestroyed == null);
 9         toBeDestroyed = currentThread;
10 
11         currentThread.status = statusFinished;
12 
13         KThread joinedKThread;
14         if (currentThread.joinQueue != null)
15             while ((joinedKThread = currentThread.joinQueue.nextThread()) != null)
16                 joinedKThread.ready();
17         sleep();
18     }


 后续测试程序如下:

package nachos.threads;

import nachos.machine.*;

public class KThreadTest {

    public KThreadTest() {
    }

    public static void simpleJoinTest() {
        KThread A_thread = new KThread(new KThreadTest.A_thread(5));
        KThread B_thread = new KThread(new KThreadTest.B_thread(A_thread));
        B_thread.fork();
        B_thread.join();
    }

    public static class B_thread implements Runnable {
        B_thread(KThread joinee) {
            this.joinee = joinee;
        }

        public void run() {
            System.out.println("B_thread 就绪");
            System.out.println("Forking and joining A_thread...");
            this.joinee.fork();//Causes this thread to begin execution.
            this.joinee.join();//启动a线程,阻塞b线程
            System.out.println("B_thread 执行结束");
        }

        private KThread joinee;
    }

    public static class A_thread implements Runnable {
        A_thread(int num) {
            this.num = num;
        }

        public void run() {
            System.out.println("A_thread 就绪");
            System.out.println("A_thread开始执行");

            // This should just kill some cycles
            for (int i = 0; i < this.num; ++i) {
                System.out.println("A_thread 循环 第" + i + " 次");
                KThread.currentThread().yield();
            }
            System.out.println("A_thread 执行结束");
        }
        private int num;
    }
    
}

 

原文地址:https://www.cnblogs.com/BambooEatPanda/p/4921817.html