【问题标题】:Does Peterson's algorithm satisfy starvation?彼得森算法是否满足饥饿?
【发布时间】:2010-10-27 13:26:25
【问题描述】:

我一直在搜索有关 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;

该算法使用两个变量,标志和转弯。标志值为 1 表示进程想要进入临界区。变量 turn 保存轮到它的进程的 ID。如果 P1 不想进入其临界区,或者如果 P1 通过将 turn 设置为 0 优先于 P0,则允许进程 P0 进入临界区。

【问题讨论】:

  • 如果您提出问题,请为不熟悉您所谈论的主题的人提供更多背景信息。它是什么样的算法?它能做什么?你的确切问题是什么?如果您这样做,社区将非常感激。

标签: algorithm deadlock solution


【解决方案1】:

正如 Ben Jackson 所怀疑的,问题出在广义算法上。标准的 2 进程 Peterson 算法满足无饥饿特性。

显然,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 的死锁场景:

  • 进程 0 首先启动,设置 pos[0] = 0step[0] = 0,然后等待。
  • 接下来开始进程 2,设置 pos[2] = 0step[0] = 2,然后等待。
  • 进程 1 最后启动,设置 pos[1] = 0step[0] = 1,然后等待。
  • 进程 2 最先注意到 step[0] 的变化,因此设置了 j = 1pos[2] = 1step[1] = 2
  • 进程 0 和 1 被阻止,因为 pos[2] 很大。
  • 进程 2 未被阻止,因此它设置为 j = 2。它逃脱了 for 循环并进入了关键部分。完成后,它会设置pos[2] = 0,但会立即再次开始竞争临界区,从而设置step[0] = 2 并等待。
  • 进程 1 最先注意到 step[0] 的变化,并作为之前的进程 2 继续进行。
  • ...
  • 进程 1 和 2 轮流击败进程 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)。

【讨论】:

  • 我希望我可以访问学术论文。 ://
【解决方案2】:

Rex 在死锁情况下是错误的。
(附带说明:正确的术语是饥饿场景,因为对于死锁,至少需要两个线程才能“卡住”,请参阅维基百科:deadlockstarvation

随着进程 2 和 1 进入级别 0,step[0] 被设置为 1 或 2,从而使进程 0 的提前条件为假,因为 step[0] == 0 为假。

2 个进程的彼得森算法稍微简单一些,并且可以防止饥饿。

n 个进程的 Peterson 算法要复杂得多

如果出现进程饿死的情况,step[j] == i and some_pos_is_big(i, j) 必须永远为真。这意味着没有其他进程进入同一级别(这将使step[j] == i 为假)并且至少有一个进程始终与 i 处于同一级别或更高级别(以保证some_pos_is_big(i, j) 保持为真)

此外,在这个级别j中只能死锁一个进程。如果两个陷入僵局,那么其中一个 step[j] == i 将是错误的,因此不会陷入僵局。 所以这意味着没有进程不能进入同一级别,并且必须始终有一个进程在上一级。

由于没有其他进程可以加入上述进程(因为它们不能进入级别 j,因此不能超过 lelel j),至少一个进程必须死锁太高,否则临界区中的进程不会释放临界区。

如果我们假设临界区中的进程在有限时间后终止,那么上述进程中只有一个必须死锁。

但是要使那个死锁,上面的另一个必须死锁等等。 但是,上面只有有限的进程,所以最终top进程不会死锁,因为一旦释放了临界区,它就会前进。

因此,n 个进程的 peterson 算法可以防止饥饿!

【讨论】:

    【解决方案3】:

    我怀疑关于饥饿的评论是关于一些广义的 N 过程彼得森算法。可以构建一个有界等待的 N 进程版本,但如果没有一个特别讨论的版本,我们无法说明为什么特定的泛化可能会受到饥饿的影响。

    一个快速的谷歌出现了this paper,其中包括伪代码。如您所见,通用版本要复杂得多(而且价格昂贵)。

    【讨论】:

    • 链接不可用。
    猜你喜欢
    • 1970-01-01
    • 2013-02-17
    • 2011-02-24
    • 2010-11-12
    • 2017-05-05
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多