我正在尝试理解彼得森的算法,但我遇到了这个问题。我追踪了代码并写了我的观察结果。请检查我的观察,我是否在正确的轨道上?
教科书中的 问题 :假设只有两个进程,一个pid
值0,另一个pid
值为1这个并发算法有什么问题?
while(True)
{
flag[pid] = 1
turn = 1-pid
while( flag[1-pid] && turn == 1-pid ); // busy wait
// critical section
...
// end of critical section
flag[pid] = 0
}
跟踪代码:
---------- Process 0: ---------- | ---------- Process 1: ----------
|
pid = 0 | pid = 1
flag[0] = 1 | flag[1] = 1
turn = 1 - 0 = 1 | turn = 1 - 1 = 0
|
while (flag[1 - 0] | while (flag[1 - 1]
&& turn == (1 - 0)) | && turn == (1 - 1))
|
// --> while (flag [1] && true) | // --> while (flag [0] && true)
// --> while (flag [1]) | // --> while (flag [0])
我的观察
0
的流程之一出来时
它循环然后它可以将它标记为false
(flag[0] = 0
)并导致
其他进程不运行。因此,流程0
可以运行两次,流程1根本不运行。此外,它还可能导致流程1
饿死,反之亦然。答案 0 :(得分:5)
彼得森的算法保证在没有任何饥饿的情况下访问两个进程的关键部分。
flag
表示希望输入critical section
。turn
允许其他完成等待并继续critical section
。critical section
的工作时,它表明它的愿望消失了(flag[pid] = False
)。这允许另一个进入该部分。但是,如果一个进程由于上下文切换而打开和关闭它flag
而没有另一个注意到它,它仍然必须切换它的turn
标志。 彼得森的算法有效,因为每个流程都有以下心态:
I would like to access the critical section. So, I'll wait my turn
所以你看,最终一切顺利就好了。没有饥饿,每个流程都会没有 卡住,并且两个进程都会访问关键部分再次。