ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Pintos 实验1 Mission2记录(下)

2021-11-01 21:03:53  阅读:309  来源: 互联网

标签:优先级 测试点 记录 主线 Pintos priority 线程 Mission2 donate


  上期说到,我们把优先级调度做好了。

  现在是实现优先级捐赠。

  本实验是基于和LX同学一起在5教站了一下午的基础上才写出来的,这篇报告有LX同学大于或等于于一半的功劳。

  我先和LX同学一起看了各个测试点,整理思路,我这篇文章也按照这个顺序来写。

做题第一步:先遍历所有测试点

  1.priority-donate-chain

   2.priority-donate-lower

 

 

 

 

 

这个测试点主要是改变了原始线程的优先级,但是因为它还持有其他线程正在等待的锁,所以优先级不能降低,但测试点要求我们保存该设置操作,在锁释放之后要能看到影响。

  3.priority-donate-multiple

 

 

 

  这个测试点主要是用优先级为31的主线程申请了两个锁a、b,先后用优先级为32、33的线程A,线程B(大写用来区分)来申请锁a、b,导致主线程的优先级变成32,接着又变成33.

  随后主线程释放b锁,此时主线程优先级应当变回32,B立即运行(优先级33比其他都高了),之后主线程运行,解锁a锁,优先级变成31,A立即运行,结束后主线程接着运行,结束。

  这个测试点的主要要点在于解锁后可能需要下调优先级,并让出CPU,但不能一次性下降到最早的优先级,因为还持有其他线程正在等待的锁。

  4.priority-donate-multiple2

  

 

  这个和上一个测试点很接近,但主线程先释放手中的对应优先级低的线程所申请的锁,此时主线程优先级不应该改变。

 

 

   5.priority-donate-nest

 

首先,主线程(31、low priority)初始化两个锁a、b,并持有b,然后创建一个medium线程(32)持有b锁,申请a锁,那么主线程优先级变成32,再创建一个high线程(33)申请b锁,此时medium优先级捐赠应该变成33

,递归地:主线程优先级应该也变成33.随后释放a锁,medium获得a锁运行,接着释放a,然后释放b,此时high抢占CPU,运行结束,medium结束,low结束。

这个测试点的要点还是在于优先级的捐赠与递归

 

   6.priority-donate-one

  (simple routine doesn't deserve my effort.jpg)

  就是主线程(31)分别创建两个线程(32、33)申请主线程持有的锁,于是主线程的优先级变成32、33。主线程释放锁之后,33那个线程先运行结束,然后32,然后主线程。

  7.priority-donate-sema

 

 

 

 

 

在这个测试点中,主线程先创建了一个lock和一个信号量sema,它先创建一个low(32),拿到锁,申请信号量,但是此时信号量为0,low被阻塞。

主线程再创建一个med(34)申请lock,但锁已经被占有了,low优先级变成34。加入某个时间点med拿到锁,它还会执行sema_down

最后主线程创建了一个high线程(36)申请锁,如果它拿到了锁,他会执行sema_up。

这个测试点的要点在于,当主线程sema_up之后,low运行,释放锁,此时必须由优先级较高的high拿到锁,否则med会请求sema_down,最终死锁。

 

 实现思路

  测试点看完了,开始整理思路,先从priority-donate-one开始,最基本的就是当申请锁时,要判断现在锁是否被持有,如果没有,那拿着就行,否则要把优先级传递给现在的持有者。

  但是priority-donate-chain告诉我们,这个持有者有可能也正在等待其他的线程持有的锁,所以需要实现递归捐赠。

  首先我们利用锁数据结构里的holder,在某一个线程申请锁且发现锁被占有的时候,判断这个holder的优先级是不是比自己的低,如果是就要捐赠,并且递归地区看这个holder有无在等待的锁,所以我们在struct thread这一个数据结构里还要加一个变量waiting_lock,用来存正在等待的锁,这样就可以构成一个链表递归调用了。

 

  thread里面增加一个 struct lock* waiting_lock。

 

   

 

thread的初始化要加上我们新增的三个变量

 

lock_acquire函数

 

 

优先级的递归捐赠

 

   释放锁以及thread_set_priority的时候,要考虑到目前的这个线程是不是还持有别人正在等待的锁,优先级不能随便降低;但是与此同时thread_set_priority函数必须起作用,不能被“吞掉”,那么我们将它起的作用保存起来,作为实际的优先级old_priority,如果在释放锁的时候还要遍历自己持有的其他锁,观察其每一个的优先级最高的等待者的优先级,和old_priority结合起来取最大值作为表现出来的priority,也就是数据结构里面的priority。

  thread数据结构在前面已经提到了。主要post一下thread_set_priority和lock_release。

  

 thread_set_priority函数

 lock_release函数

  priority-donate-sema告诉我们,在两个优先级不一样的线程等待同一个锁的时候,要由优先级高的获得,这个我们只要在把当前线程插入到lock里的sema的waiter队列里的时候按顺序插入即可,这个对sema_down的修改在改为优先级调度时就已经做过了。

 

标签:优先级,测试点,记录,主线,Pintos,priority,线程,Mission2,donate
来源: https://www.cnblogs.com/myendless/p/15496125.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有