📜  操作系统 | 17套

📅  最后修改于: 2021-09-27 06:19:36             🧑  作者: Mango

以下问题已在 GATE 2012 CS 考试中提出。

Fetch_And_Add(X,i) 是一个原子性的 Read-Modify-Write 指令,它读取内存位置 X 的值,将其增加值 i,并返回 X 的旧值。它在下面显示的伪代码中用于实现一个忙等待锁。 L是初始化为0的无符号整数共享变量。0的值对应锁可用,而任何非零值对应锁不可用。

AcquireLock(L){
         while (Fetch_And_Add(L,1))
               L = 1;
   }
  ReleaseLock(L){
         L = 0;
   } 

这个实现
(A) 失败,因为 L 可能溢出
(B) 失败,因为当锁实际可用时 L 可以采用非零值
(C) 工作正常,但可能会使某些进程挨饿
(D) 在没有饥饿的情况下正常工作

答案 (B)
仔细看看下面的while循环。

while (Fetch_And_Add(L,1))
               L = 1;  // A waiting process can be here just after 
                       // the lock is released, and can make L = 1.

考虑一个进程刚刚释放锁并使 L = 0 的情况。让另一个进程等待锁,意味着执行 AcquireLock()函数。在 L 被设为 0 之后,让等待进程执行 L = 1 行。现在,锁可用并且 L = 1。由于 L 是 1,等待进程(以及任何其他未来的进程)不能出来while 循环的。

上述问题可以通过将 AcuireLock() 更改为以下来解决。

AcquireLock(L){
         while (Fetch_And_Add(L,1))
         { // Do Nothing }
   }

请参阅 GATE Corner 了解所有往年论文/解决方案/解释、教学大纲、重要日期、笔记等。