bool flag[2] = {false, false}
process p(i): // i in { 0, 1 }
while (flag[1-i]) {
// do nothing
}
flag[i] = true
while (flag[1-i]) {
// do nothing
}
<critical section>
flag[i] = false
这段代码让我发疯。它是为解决两个程序(0,1)之间的互斥而构建的代码。 有人可以解释一下,当放入代码时,每个程序0和1的标志如何变化。
答案 0 :(得分:0)
2个布尔值flag
的数组必须位于共享内存中才能有效。对于流程而言,这至关重要;如果这些是线程,那么你不需要共享内存。
最初,进程0或1都没有将其flag
值设置为true
。
假设进程i = 0
尝试访问关键部分。第一个忙循环(while
循环)等待flag[1]
为false
(此时它为假);然后代码集flag[0] = true
。代码现在进入第二个忙循环; flag[1]
仍为false
,因此它会继续安全地进入关键部分,因为知道其他进程也不在关键部分。
假设当进程0处于临界区时,进程1也尝试输入它。它在第一个忙循环中被阻止,因为flag[0]
为真。它仍然是这样,直到进程0离开并将flag[0]
设置为false。当进程0离开时,进程1将flag[1]
设置为true,进入第二个busy循环,然后离开,因为flag[0]
为false;它现在处于关键部分。
为什么两个忙循环?因为两个进程可能同时在多个核上运行,并且两者都可能同时进入第一个繁忙的循环。他们都会看到另一个标志是假的,退出循环并将自己的标志设置为true,并重新检查其他标志是否仍为假。大多数时候,其中一个人会看到其他人是假的并且会进入关键部分。偶尔,他们可能都发现其他人是真的(因为他们在锁定步骤中工作太多了),然后两者都会进入第二个忙循环,并且都不会退出 - 死锁。
所以,我并不相信代码是一个万无一失的互斥机制,尽管它需要运气不好才能陷入僵局。但是,如果有足够的尝试,就会出现运气不好的情况 - 长期运行的流程无法承担风险。