while(true)
{
waiting[i] = true;
while (waiting[i] && test_and_set(&lock)) ;
waiting[i] = false;
/* critical section */
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
else
waiting[j] = false;
/* remainder section */
}
考虑过程P(i)进入入口部分的情况。最初锁定是错误的。当它进入入口部分时,while循环终止,进程P(i)进入临界区,lock = true。
当它超出临界区并找到正在等待进入临界区的进程P(j)时,例如在最后一行代码中,即在剩余部分中有一个上下文切换并且进程P(j)进入进入部分。 在此位置锁定为真,等待[j]也变为真。 当它到达while循环时,它应该永远不会结束。 那么,过程P(j)将如何进入关键部分?
我做错了吗? 解释
答案 0 :(得分:1)
当你P(j)
进入条目时,你是对的,lock
是true
而waiting[j]
也是true
。因此,进程P(j)
会陷入while循环(称为自旋锁)。
现在假设context switch
也从流程P(j)
发回P(i)
。我们处于流程P(i)
的关键部分之外,现在执行以下代码:
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
所以j = i + 1
和条件(j != i) && !waiting[j]
变为真(假设等待每个进程初始化为false)。
然后j
采用以下值:
i + 2 , i + 3, ......0 , 1 , 2 , 3 , 4....i
由于%
运算符而发生值的回滚。
当j
变为i
条件(j != i) && !waiting[j]
变为false
时,由于
false
if (j == i)
lock = false;
最终进程P(i)
终止并且最终将context switch
处理P(j)
,并且因为test和set指令返回旧值条件
(waiting[i] && test_and_set(&lock))
将成为false
,因为test_and_set(&lock)
会返回false
而P(j)
会突破自旋锁并且会进入关键部分