相互排斥问题

时间:2009-01-04 19:06:48

标签: mutex

请查看以下伪代码:

boolean blocked[2];
int turn;
void P(int id) {
      while(true) {
             blocked[id] = true;
             while(turn != id) {
                    while(blocked[1-id])
                    /* do nothing */;
                    turn = id;
             }
             /* critical section */
             blocked[id] = false;
             /* remainder */
      }
}
void main() {
      blocked[0] = false;
      blocked[1] = false;
      turn = 0;
      parbegin(P(0), P(1)); //RUN P0 and P1 parallel
}

我认为可以使用上面的代码实现一个简单的Mutual-Exclution解决方案。但它不起作用。有谁知道为什么?

真的很感激任何帮助!

6 个答案:

答案 0 :(得分:5)

由于以下原因,相互排除在此示例中无法保证:

我们从以下情况开始:

blocked = {false, false};
turn = 0;

P1现在执行,并跳过

  blocked[id] = false; // Not yet executed.

现在的情况是:

blocked {false, true}
turn = 0;

现在P0执行。它通过第二个while循环,准备执行临界区。当P1执行时,它设置为1,并且还准备执行临界区。

不过,这种方法最初是由海曼发明的。他于1966年将其发送给了Acm通讯公司

答案 1 :(得分:2)

由于以下原因,此示例中不会保证互斥:

我们从以下情况开始:

turn= 1;
blocked = {false, false};

执行如下:

P0: while (true) {
P0:   blocked[0] = true;
P0:   while (turn != 0) {
P0:     while (blocked[1]) {
P0:     }
P1: while (true) {
P1:   blocked[1] = true;
P1:   while (turn != 1) {
P1:   }
P1:   criticalSection(P1);
P0:     turn = 0;
P0:   while (turn != 0)
P0:   }
P0:   critcalSection(P0);

答案 2 :(得分:0)

这是家庭作业,还是一些嵌入式平台?你有什么理由不能使用pthreads或Win32(作为相关的)同步原语吗?

答案 3 :(得分:-1)

也许您需要声明阻止并转为易失性,但如果没有指定编程语言,则无法知道。

答案 4 :(得分:-1)

不能像这样实现并发,尤其是在多处理器(或多核)环境中:不同的核心/处理器具有不同的缓存。这些缓存可能不一致。下面的伪代码可以按照显示的顺序执行,结果显示为:

get blocked[0] -> false   // cpu 0
set blocked[0] = true     // cpu 1 (stored in CPU 1's L1 cache)
get blocked[0] -> false   // cpu 0 (retrieved from CPU 0's L1 cache)
get glocked[0] -> false   // cpu 2 (retrieved from main memory)

需要硬件知识才能实现并发。

答案 5 :(得分:-1)

编译器可能已经优化了“空”while循环。将变量声明为volatile可能会有所帮助,但不能保证在多处理器系统上足够。