Nachos操作系统:Pro1.1:完成KThread.join方法

问题描述

  1. Note that another thread does not have to call join(), but if it is called, it must be called only once.
  2. A thread must finish executing normally whether or not it is joined.

问题思考

#

1.KThread.join函数如果被调用也只能被调用一次,第二次调用的结果是未知的。

2.每个线程都维护自己的资源,(在Linux和Windows操作系统中,线程维护的资源存在于TCB中)换言之,每个线程拥有自己的waitJoinQueue,里面存放了由于自己的join而被阻塞无法执行的线程。

3.由于我们对每个线程添加了waitJoinQueue切里面存有在等待的线程,故而我们需要修改finish函数,在线程完成运行即将终止时检查其waitJoinQueue,唤醒队列中在等待的线程。

解决方案

(1)Kthread的join()中的Lib.assertTrue(this != currentThread)已经实现线程只能调用一次join()方法,根据要求,在调用join()方法时,让当前运行线程休眠,并将当前运行的线程加入到一个阻塞队列中。
(2)在线程结束时,finish()函数循环唤醒所有被阻塞的线程。Finish()函数在run()函数返回时自动调用,同样可以被直接调用。但当前唯一运行的线程不能被finish()函数立即结束,只有当其他线程运行时才可结束。

线程状态转换图

Nachos操作系统--join函数线程转换

实现代码

 public void join() {
    Lib.debug(dbgThread, "Joining to thread: " + toString());

    Lib.assertTrue(this != currentThread);  
    //工作
    /*if(!this.IsAlive()) return;
    while(this.IsAlive())
    {
        this.joinQueue.acquire(this);
    }
    this.joinQueue.waitForAccess(KThread.currentThread());
    KThread.sleep();//当前进程等待被调用的进程结束。*/

    /**for join method**/
    boolean intStatus = Machine.interrupt().disable(); //系统关中断
    if (status != statusFinished)
    {
        waitJoinQueue.waitForAccess(currentThread); //调用另一个要调用的进程
    KThread.sleep(); //当前进程睡眠等待被调用进程结束
    }
     Machine.interrupt().enable();
    /**for join method**/
    }
 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 waitThread= currentThread.waitJoinQueue.nextThread(); //调用等待队列上的第一个进程; //调用等待队列上的第一个进程
    while (waitThread != null) //while
    {
    waitThread.ready(); //唤醒等待队列上所有被阻塞的进程
    waitThread= currentThread.waitJoinQueue.nextThread(); //调用等待队列上的第一个进程
    }
    sleep();
    //工作结束:

    //sleep();

    }

测试代码及结果nachos测试内部类

Join测试方法

结果

Test1

这里只测试了Test1
方法,
可以看到,实现了join方法。至此,pro1.1

已经全部实现了。

需要注意的几个地方

1.join:Kthread的join()中的Lib.assertTrue(this != currentThread)已经实现线程只能调用一次join()方法。还有finish函数的调用:Finish()函数在run()函数返回时自动调用,同样可以被直接调用。但当前唯一运行的线程不能被finish()函数立即结束,finish函数的测试也花费了一些时间。
waitJoinQueue的初始化要求在每个线程中都得到执行,不然会爆空指针异常,后来发现是finish的if 和while循环的差别。
2.Joincounter静态全局变量记录join方法被调用的次数以控制其满足题目要求
3.一定要记得修改finish方法唤醒waitJoinQueue中等待的线程

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值