请查看以下伪代码:
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解决方案。但它不起作用。有谁知道为什么?
真的很感激任何帮助!
答案 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可能会有所帮助,但不能保证在多处理器系统上足够。