Files
2021-08-19 18:38:31 +08:00

1.6 KiB
Raw Permalink Blame History

6.7 睡眠锁

有时xv6需要长时间保持锁。例如文件系统第8章在磁盘上读写文件内容时保持文件锁定这些磁盘操作可能需要几十毫秒。如果另一个进程想要获取自旋锁那么长时间保持自旋锁会导致获取进程在自旋时浪费很长时间的CPU。自旋锁的另一个缺点是一个进程在持有自旋锁的同时不能让出yieldCPU然而我们希望持有锁的进程等待磁盘I/O的时候其他进程可以使用CPU。持有自旋锁时让步是非法的因为如果第二个线程试图获取自旋锁就可能导致死锁因为acquire不会让出CPU第二个线程的自旋可能会阻止第一个线程运行并释放锁。在持有锁时让步也违反了在持有自旋锁时中断必须关闭的要求。因此我们想要一种锁它在等待获取锁时让出CPU并允许在持有锁时让步以及中断

Xv6以睡眠锁sleep-locks的形式提供了这种锁。acquiresleep (kernel/sleeplock.c:22) 在等待时让步CPU使用的技术将在第7章中解释。在更高层次上睡眠锁有一个被自旋锁保护的锁定字段acquiresleepsleep的调用原子地让出CPU并释放自旋锁。结果是其他线程可以在acquiresleep等待时执行。

因为睡眠锁保持中断使能,所以它们不能用在中断处理程序中。因为acquiresleep可能会让出CPU所以睡眠锁不能在自旋锁临界区域中使用尽管自旋锁可以在睡眠锁临界区域中使用

因为等待会浪费CPU时间所以自旋锁最适合短的临界区域睡眠锁对于冗长的操作效果很好。