解释为什么这个算法不能保证相互排斥

时间:2014-12-14 17:15:45

标签: algorithm concurrency mutual-exclusion

考虑以下“忙等待”尝试互斥算法。 解释为什么这不能保证相互排斥。我无法弄清楚它为什么没有,对我而言,任何人都应该解释为什么它不会?

/*Process0 */
while (flag[1]) do {/* nothing */}
flag[0] = true;
/*critical section */
flag[0] = false;

/*Process1 */
while (flag[0]) do {/* nothing */}
flag[1] = true;
/*critical section */
flag[1] = false;

2 个答案:

答案 0 :(得分:2)

它不起作用,因为你显然认为原子(即,不可分割)的东西不属于任何类型。

现在,您似乎假设只要一个进程中的while循环退出,执行将至少继续执行flag[N]的全部分配而不进行任何上下文切换。

这根本不是真的。为了论证,让我们将每个过程分解为A部分(while循环)和B部分(临界部分)。完全有可能有这样的序列:

1A
2A
1B [for a while, then interrupted by context switch]
2B [for a while, then interrupted by context switch]
1B [resumes after context switch]
2B [resumes after context switch]

完全这种代码在99.9%的情况下有效。你可以在几个月内疯狂地测试它,并且它似乎似乎它完美无瑕 - 然后你在客户面前演示它,它崩溃,灼伤,并摧毁它环境。然后你把它发回实验室,尽管他们愿意,但他们不能复制这个问题。

答案 1 :(得分:0)

这里可能会发生两件事。

  1. 您可以同时运行两个(或更多)进程。任何人都可以抓住

    while(flag [1])do {/ * nothing * /}      //两个进程可能会同时清除标志

     flag[0] = true;  // Two process set the flag
    
  2. 您可以进行上下文切换

    while(flag [1])do {/ * nothing * /}      //进程在这里被阻止

        // Some other process sets flag [0]
    
     flag[0] = true;  // Gets set for a second time