我一直在搜索关于Peterson's algorithm的信息,但是已经发现了一些参考文献,说明它不满足饥饿但只是死锁。这是真的?若有,有人可以详细说明为什么不呢?
彼得森的算法:flag[0] = 0;
flag[1] = 0;
turn;
P0: flag[0] = 1;
turn = 1;
while (flag[1] == 1 && turn == 1)
{
// busy wait
}
// critical section
...
// end of critical section
flag[0] = 0;
P1: flag[1] = 1;
turn = 0;
while (flag[0] == 1 && turn == 0)
{
// busy wait
}
// critical section
...
// end of critical section
flag[1] = 0;
算法使用两个变量,flag和turn。标志值为1表示进程想要进入临界区。变量turn保存转过程的ID。如果P1不想进入其临界区,或者如果P1通过将转到0设置为优先于P0,则允许进程P0进入临界区。
答案 0 :(得分:9)
正如Ben Jackson所怀疑的那样,问题在于广义算法。标准的2过程Peterson算法满足无饥饿特性。
显然,彼得森的原始论文实际上有N
处理器的算法。这是我刚刚用C ++语言编写的草图,据说是这个算法:
// Shared resources
int pos[N], step[N];
// Individual process code
void process(int i) {
int j;
for( j = 0; j < N-1; j++ ) {
pos[i] = j;
step[j] = i;
while( step[j] == i and some_pos_is_big(i, j) )
; // busy wait
}
// insert critical section here!
pos[i] = 0;
}
bool some_pos_is_big(int i, int j) {
int k;
for( k = 0; k < N-1; k++ )
if( k != i and pos[k] >= j )
return true;
}
return false;
}
这是N = 3
的死锁情景:
pos[0] = 0
和step[0] = 0
,然后等待。pos[2] = 0
和step[0] = 2
,然后等待。pos[1] = 0
和step[0] = 1
,然后等待。step[0]
中的更改,因此设置了j = 1
,pos[2] = 1
和step[1] = 2
。pos[2]
很大。j = 2
。它从for循环中逃脱并进入临界区。完成后,它会设置pos[2] = 0
,但会立即再次开始竞争关键部分,从而设置step[0] = 2
并等待。step[0]
中的更改并在此之前继续进行的流程。 参考。所有细节均来自Alagarsamy的论文“Some myths about famous mutual exclusion algorithms”。显然Block和Woo在“A more efficient generalization of Peterson's mutual exclusion algorithm”中提出了一个确实满足无饥饿的修改算法,Alagarsamy后来在“A mutual exclusion algorithm with optimally bounded bypasses”中得到了改进(通过获得最佳饥饿界限N-1
)。 / p>
答案 1 :(得分:2)
雷克斯的死锁情况有问题 (作为旁注:正确的术语是饥饿场景,因为对于死锁,至少有两个线程需要被“卡住”才能看到维基百科:deadlock和starvation)
当进程2和1进入级别0时,步骤[0]被设置为1或2,从而使进程0的提前条件为假,因为step[0] == 0
为假。
2个过程的peterson算法稍微简单一些,可以防止饥饿。
n个过程的peterson算法要复杂得多
如果某个过程匮乏条件step[j] == i and some_pos_is_big(i, j)
,则必须永远为真。这意味着没有其他进程进入同一级别(这将使step[j] == i
为false)并且至少一个进程始终与i处于同一级别或更高级别(以保证some_pos_is_big(i, j)
是保持真实)
此外,只有一个进程可以在此级j
中死锁。如果两个人陷入僵局,那么其中一人step[j] == i
将是假的,因此不会陷入僵局。
因此,这意味着任何流程都无法进入同一级别,并且必须始终存在上述级别的流程。
由于没有其他进程可以加入上述进程(因为它们无法进入j级,因此不能超过lelel j)至少有一个进程必须死锁,或者临界区中的进程不会释放关键部分。
如果我们假设临界区中的进程在有限时间后终止,那么上述进程中只有一个必须是死锁的。
但是对于那个陷入僵局的人来说,上面的另一个必须陷入僵局等等。 但是,上面只有有限的过程,因此最终的过程不会陷入僵局,因为一旦关键部分被释放,它就会前进。
因此n进程的peterson算法可以防止饥饿!
答案 2 :(得分:0)
我怀疑关于饥饿的评论是关于一些广义的,N过程的彼得森算法。有可能构造一个有限等待的N过程版本,但没有特别讨论我们不能说为什么特定的泛化可能会受到饥饿。
快速Google出现了this paper,其中包括伪代码。如您所见,通用版本要复杂得多(而且价格昂贵)。