试图理解彼得森的算法

时间:2014-11-01 21:24:04

标签: c multithreading algorithm concurrency process

我正在尝试理解彼得森的算法,但我遇到了这个问题。我追踪了代码并写了我的观察结果。请检查我的观察,我是否在正确的轨道上?

教科书中的

问题 :假设只有两个进程,一个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])

我的观察

  1. 我认为在忙碌的等待部分,两个while循环都可以运行 永远。
  2. 我也认为当流程0的流程之一出来时 它循环然后它可以将它标记为falseflag[0] = 0)并导致 其他进程不运行。因此,流程0可以运行两次,流程1根本不运行。此外,它还可能导致流程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


所以你看,最终一切顺利就好了。没有饥饿,每个流程都会没有 卡住,并且两个进程都会访问关键部分再次。