2024 春夏季开源操作系统训练营 阶段二 Lab5 实验报告

本实验的练习内容是实现死锁检测。

注意:在本实验中,所有的资源都是锁 mutex 或者 semaphore,并且同时只会出现一种。

简单来讲,就是在某个线程尝试获取锁的时候,对该线程所在的进程进行死锁检测,如果发现会产生死锁,则拒绝这次获取锁的操作。具体来讲,进程会通过 sys_mutex_lock 或者 sys_semaphore_down 来获取锁,如果不会产生死锁,就正常获取锁,返回 0;如果会产生死锁,则不获取锁,直接返回 -0xdead

我们直接采用题目中提到的死锁检测算法。由于锁是以进程为单位的,也就是说一个进程的所有线程共享锁,但是进程之间不会共享锁,因此我们算法中的 availableallocationneed 这三个数组设置在 ProcessControlBlockInner 中最好。

在每次添加一个新的锁的同时,也需要往这三个数组中添加对应的元素。其中,available 就添加该锁可以获取的次数,allicationneed 则是需要向每个线程都添加一个 0,表示还没有分配和需要任何的锁。添加一个线程的时候也是同理。

sys_mutex_locksys_semaphore_down 中,我们需要进行死锁检测。首先先将当前线程需要的锁对应的 need1,然后临时新建 workfinish,按照题目的算法进行循环检测,当找不到满足条件的线程后就退出循环。如果此时 finish 都为 true,则表示此次获取锁的操作不会造成系统死锁,正常获取锁即可。否则表示当前操作会导致系统死锁,直接返回 -0xdead

当成功获取锁后,需要将对应的 need 的值添加到 allocation 中,并且减少 available 的值,表示成功将锁分配给了线程。need 也要注意清零。

当一个线程执行完毕或者调用 sys_mutex_unlonksys_semaphore_up 后,还需要将其 allocation 的值重新添加回 available,表示将锁释放。

代码并不复杂。不过有一点需要注意,processprocess_inner 要勤使用 drop() 手动释放,因为他们是使用 Arc 进行互斥访问的,如果持有后又调用了别的函数,在别的函数里获取,就会 panic。

sys_enable_deadlock_detect 的实现非常简单,在 ProcessControlBlockInner 中再添加一个 bool 表示是否启动死锁检测,修改这个 bool 就好了。

需要删除在 TaskManager 中等待执行的子线程,回收进程的 memory_setfd_tabletasks

我们并不需要主动回收,Rust 的所有权机制会自动释放资源并回收。

显然,Mutex2 的实现方式是错误的,它在队列里有别的线程的时候,只是将线程添加到了执行队列中,并没有修改 mutex_inner.locked 的值……这会导致锁其实并没有被释放。

  1. 在完成本次实验的过程(含此前学习的过程)中,我曾分别与 以下各位 就(与本次实验相关的)以下方面做过交流,还在代码中对应的位置以注释形式记录了具体的交流对象及内容:

  2. 此外,我也参考了 以下资料 ,还在代码中对应的位置以注释形式记录了具体的参考来源及内容:

  3. 我独立完成了本次实验除以上方面之外的所有工作,包括代码与文档。 我清楚地知道,从以上方面获得的信息在一定程度上降低了实验难度,可能会影响起评分。

  4. 我从未使用过他人的代码,不管是原封不动地复制,还是经过了某些等价转换。 我未曾也不会向他人(含此后各届同学)复制或公开我的实验代码,我有义务妥善保管好它们。 我提交至本实验的评测系统的代码,均无意于破坏或妨碍任何计算机系统的正常运转。 我清楚地知道,以上情况均为本课程纪律所禁止,若违反,对应的实验成绩将按“-100”分计。