📜  门| GATE CS 2012 |问题30

📅  最后修改于: 2021-07-02 14:52:08             🧑  作者: Mango

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 }
   }

仅当数量大于“ int”大小的进程执行while循环的检查条件而不是L = 1(即需要先占)时,才会发生溢出。
但是,当L为1时,该过程将在while循环中重复进行-没有溢出,因为在每次递增到L后,L再次等于1。
选项(b)是选项(a)的最佳选择。

资料来源:http://www.geeksforgeeks.org/operating-systems-set-17/

这个问题的测验