对比Peterson和Dekker的算法


41

我试图理解Peterson和Dekker的算法,它们非常相似并且显示出很多对称性。

我试图用非正式语言来制定算法,如下所示:

Peterson's: "I want to enter."                 flag[0]=true;
            "You can enter next."              turn=1;
            "If you want to enter and          while(flag[1]==true&&turn==1){
            it's your turn I'll wait."         }
            Else: Enter CS!                    // CS
            "I don't want to enter any more."  flag[0]=false;

Dekker's:   "I want to enter."                 flag[0]=true;
            "If you want to enter              while(flag[1]==true){
             and if it's your turn               if(turn!=0){
             I don't want to enter any more."      flag[0]=false;
            "If it's your turn                     while(turn!=0){
             I'll wait."                           }
            "I want to enter."                     flag[0]=true;
                                                 }
                                               }
            Enter CS!                          // CS
            "You can enter next."              turn=1;
            "I don't want to enter any more."  flag[0]=false;

差异似乎是发生在Dekker的地点"You can enter next."和发生的事实"if it's your turn I don't want to enter any more."

在彼得森的算法中,这两个过程似乎占主导地位。除非轮到对方,否则一个过程似乎迫使他进入了关键部分。

相反,在Dekker的算法中,这两个过程似乎是顺从而礼貌的。如果两个过程都想进入关键部分,而轮到另一个,则该过程决定不再要进入。(饥饿自由需要吗?为什么?)

这些算法到底有何不同?我想象当两个过程都试图进入关键部分时,在Peterson的过程中,过程说“我进入”,而在Dekker的过程中,过程中说“您可以进入”。有人可以弄清楚每种算法中流程的行为方式吗?我用非正式的说法表达的方式正确吗?


请注意,Peterson的算法不能完全解决临界区问题,因为对标志本身的读取和写入本身就是临界区问题。Henk JM Goeman撰写的一篇真正可以完全解决该问题的论文是“仲裁者:一种用于实现同步基元的有源系统组件”。
user3083171 2015年

Answers:


24

您对算法的非正式描述非常棒。

我认为在这两种情况下,作者都试图提出一种最简单的解决方案,他们可以想到这可以确保相互排斥和死锁自由。 两种算法都不是饥饿的,也不公平的。[ed:如评论中所指出,Peterson的算法是无饥饿且公平的]。Dekker的解决方案是第一个仅使用加载和存储指令的互斥算法。它是在Edsger W.的Dijkstra引入的“协作顺序过程”,在F. Genuys编辑,《编程语言:北约高级研究学院》,第43-112页,学术出版社,1968年。如果您通读本文,您会发现Dijkstra进行了许多尝试,发现了每种问题,然后为下一个版本增加了一些尝试。他的算法效率低下的部分原因是,他先从转弯算法开始,然后尝试对其进行修改,以使过程按任意顺序进行。(不仅是0、1、0、1 ...)

经过十多年的经验和对Dekker算法的后见之明,Peterson的算法于1981年发布。Peterson想要一种比Dekker更简单的算法,以便更容易证明正确性。您可以从他的论文标题中看到他对社区感到沮丧。 彼得森(GL);“关于互斥问题的神话,” Inf。进程 来吧 ,12(3):115-116,1981。快速阅读,写得很好。(关于形式方法的愚蠢言论是无价的。)彼得森的论文还讨论了他从更简单的尝试中构建解决方案的过程。(因为他的解决方案更简单,所以需要更少的中间步骤。)请注意,主要区别(您称其为“主导”而不是“顺从”)是因为Peterson是从头开始的(不是从Dijkstra的转弯算法开始的) )他的等待循环更简单,更高效。他意识到,只要Dijkstra每次都必须退出并重试,他就可以通过简单的循环测试来摆脱困境。

我觉得我还必须提到Lamport的经典Bakery算法论文:Lamport,Leslie;“ Dijkstra并发编程问题的新解决方案”,Comm ACM 17(8):453-455,1974。Bakery算法可以说比Dekker算法更简单(并且在两个以上处理器的情况下肯定更简单),并且经过专门设计以具有容错能力。我特别提到它有两个原因。首先,因为它提供了有关互斥问题定义的一些历史,并试图解决直到1974年。其次,因为Bakery算法证明不需要硬件原子来解决互斥问题。

最后,我的一个特别喜欢的人是莱斯利的兰莫特;“快速互斥算法”,ACM Trans。比较 Sys。,5(1):1-11,1987。在本文中,Lamport试图优化针对(常见)关键部分没有争用的互斥问题的解决方案。同样,它保证相互排斥和僵局自由,但不保证公平。(我相信)这是第一个仅使用普通读写的互斥算法,可以在没有争用的情况下在O(1)时间内同步N个处理器。(发生争用时,它会退回到O(N)测试中。)他非正式地演示了在无争用的情况下,您能做的最好的事情是七个内存访问。(Dekker和Peterson都使用4,但是它们只能处理2个处理器,将其算法扩展到N时,它们必须添加额外的O(N)访问。)

总而言之:我想说Dekker的算法本身主要是从历史角度来看很有趣。Dijkstra的论文解释了互斥问题的重要性,并证明了它可以解决。但是,经过多年的事后分析,已经发现比Dekker的解决方案更简单(更有效)的解决方案。


3
>>两种算法都不是饥饿的,也不公平的。那是不对的。彼得森的算法无饥饿且公平。如果一个线程位于关键部分,而另一个线程正在等待循环中-一个等待的对象将进入下一个CS,即使CS中的线程快得多。

我想强调一下,彼得森的算法是饥饿而又公平的,即使只是重复user24190的评论。我不明白为什么这些年来,这个答案的作者既没有回复评论,也没有更正他的答案。(请务必在纠正问题后对我进行ping操作,以便我删除我的评论。)
Apass.Jack

购买彼得森(Peterson)的“关于互斥问题的神话”的链接:doi.org/10.1016/0020-0190
81)

彼得森(Peterson)的“关于互斥问题的神话”(Archive.org)的PDF:web.archive.org/web/20150501155424/https
//cs.nyu.edu/~lerner/…–斯特拉格

3

在接下来的论文中,我们给出了Peterson和Dekker算法(以及其他一些算法)的形式化模型,并使用模型检查器证明了它们的特性。请在下表中找到我们的结果(“ Deadlock”和“ Divergent”列指的是我们的模型,“ ME” = TRUE表示算法正确,“ Overtake” = TRUE表示算法正确)。

R. Meolic,T。Kapus,Z。Brezočnik。ACTLW-具有“除非”运算符的基于动作的计算树逻辑。情报科学,178(6),1542-1557,2008。

https://doi.org/10.1016/j.ins.2007.10.023

在此处输入图片说明


1

彼得森算法有一个更严格的在进入临界区的压力,其中,作为德克尔的算法是相对较软的较少侵略性。为了更加清楚,让我们看一个有关伊朗文化的例子。在进入这个例子之前,很高兴知道伊朗人进入某个地方时彼此之间有一种真正的柔和的举止!猜猜有两个伊朗人要进入一所房子,那所房子只有一扇门可以进入。

现在想象一下来自另一种文化(僵尸文化)的两个人,他们实际上在进入某个地方时并不太关心彼此(问某人是否要进入是一种尊重的问题)。

为了澄清有关该问题的信息,我们可以这样说:

  • 两个伊朗人=使用Dekker算法的两个过程
  • 两个僵尸=使用Peterson算法的两个进程

因此,让我们找出在每种算法(文化)中完成的工作。以下评论适用于第一个使用Dekker算法进入房屋的伊朗男子:

p0:
   wants_to_enter[0] ← true // Goes through the house entrance
   while wants_to_enter[1] { // If the other man wants to enter too
      if turn ≠ 0 { // Then see if it is your turn or not
         wants_to_enter[0] ← false // If it is not your turn don't go furthur
         while turn ≠ 0 { // and wait until it is your turn
           // busy wait
         }
         wants_to_enter[0] ← true // when it is your turn go through the door
      }
   }

   // critical section
   ...
   turn ← 1
   wants_to_enter[0] ← false // Set the turn for the other man
   // remainder section

我们还有两个僵尸将使用彼得森算法进入房屋。这一过程如下:

P0:     
  flag[0] = true; // Goes through the house entrance
  turn = 1; // Set the turn for himself
  while (flag[1] && turn == 1) // Wait until the other one is going in
  {
   // busy wait
  }
   // critical section
      ...
   // end of critical section
  flag[0] = false; // Done going inside

值得一提的是,他们两个都没有进入对方的行列时互斥),但是伊朗人民却变得更加柔和。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.