Algoritmi di Peterson e Dekker in contrasto


41

Sto cercando di capire gli algoritmi di Peterson e Dekker che sono molto simili e mostrano molte simmetrie.

Ho provato a formulare gli algoritmi in un linguaggio informale come segue:

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;

La differenza sembra essere il punto in cui si "You can enter next."verifica e il fatto che si "if it's your turn I don't want to enter any more."verifica in Dekker.

Nell'algoritmo di Peterson, i due processi sembrano essere dominanti. Un processo sembra farsi strada nella sezione critica a meno che non sia il turno dell'altro.

Al contrario, nell'algoritmo di Dekker, i due processi sembrano essere sottomessi ed educati. Se entrambi i processi vogliono entrare nella sezione critica, ed è il turno dell'altro, il processo decide di non voler più entrare. (È necessario per la libertà da fame? Perché?)

In che modo differiscono esattamente questi algoritmi? Immagino che quando entrambi i processi provano ad entrare nella sezione critica, in Peterson, il processo dice "I enter", mentre in Dekker il processo dice "Puoi entrare". Qualcuno può chiarire il modo in cui i processi si comportano in ciascun algoritmo? Il mio modo di dirlo in termini informali è corretto?


Si noti che l'algoritmo di Peterson non risolve completamente il problema della sezione critica, poiché le letture e le scritture nei flag stessi sono problemi della sezione critica. Un articolo che risolve completamente il problema è "The Arbiter: un componente di sistema attivo per l'implementazione della sincronizzazione dei primitivi", di Henk JM Goeman.
user3083171,

Risposte:


24

Le tue descrizioni informali degli algoritmi sono meravigliose.

Penso che in entrambi i casi l'autore stesse cercando di trovare la soluzione più semplice a cui potevano pensare che garantisse l'esclusione reciproca e la libertà di deadlock. Nessuno dei due algoritmi è esente da fame o equo.[ndr: come sottolineato nei commenti, l'algoritmo di Peterson è privo di fame e giusto]. La soluzione di Dekker era il primo algoritmo di esclusione reciproca che utilizzava solo le istruzioni di caricamento e memorizzazione. Fu introdotto in Dijkstra, Edsger W .; "Cooperating sequential processi", in F. Genuys, ed., Linguaggi di programmazione: NATO Advanced Study Institute , pp. 43-112, Academic Press, 1968 . Se leggi il documento, vedi Dijkstra lavorare attraverso una serie di tentativi, riconoscendo il problema con ciascuno di essi e aggiungendo un po 'di più per la versione successiva. Parte dell'inefficienza del suo algoritmo deriva dal fatto che inizia con un algoritmo di svolta e quindi cerca di modificarlo per consentire ai processi di progredire in qualsiasi ordine. (Non solo 0,1,0,1, ...)

L'algoritmo di Peterson fu pubblicato nel 1981, dopo oltre un decennio di esperienza e senno di poi sull'algoritmo di Dekker. Peterson voleva un algoritmo molto più semplice di Dekker in modo che la prova della correttezza fosse molto più semplice. Puoi vedere che stava provando una certa frustrazione per la comunità dal titolo del suo articolo. Peterson, GL; "Miti sul problema dell'esclusione reciproca", Inf. Proc. Lett. , 12 (3): 115-116, 1981. Lettura molto rapida e scritta molto bene. (E le sprezzanti osservazioni sui metodi formali non hanno prezzo.) Il documento di Peterson discute anche del processo attraverso il quale ha costruito la sua soluzione da tentativi più semplici. (Dato che la sua soluzione è più semplice, ha richiesto meno passaggi intermedi.) Nota che la differenza principale (quella che chiami "dominanza" piuttosto che "sottomissione") è che perché Peterson è partito da zero (non dall'algoritmo di svolta Dijkstra ha iniziato con ) il suo ciclo di attesa è più semplice ed efficiente. Si rende conto che può semplicemente cavarsela con semplici test in loop mentre Dijkstra deve eseguire il backoff e riprovare ogni volta.

Sento di dover menzionare anche il classico documento dell'algoritmo di Lamport : Lamport, Leslie; "Una nuova soluzione del problema di programmazione concorrente di Dijkstra", Comm ACM 17 (8): 453-455, 1974 . L'algoritmo di Bakery è probabilmente più semplice dell'algoritmo di Dekker (e certamente più semplice nel caso di più di 2 processori), ed è specificamente progettato per tollerare i guasti. Lo menziono specificamente per due motivi. In primo luogo, perché fornisce un po 'di storia sulla definizione del problema di esclusione reciproca e tenta di risolverlo fino al 1974. In secondo luogo perché l'algoritmo di Bakery dimostra che non è necessaria alcuna atomicità hardware per risolvere il problema di esclusione reciproca.

Infine, uno dei miei preferiti in particolare è Lamport, Leslie; "Un rapido algoritmo di esclusione reciproca", ACM Trans. Comp. Sys. , 5 (1): 1-11, 1987. In questo articolo Lamport stava cercando di ottimizzare una soluzione al problema dell'esclusione reciproca nel caso (comune) che vi fosse poca contesa per la sezione critica. Ancora una volta, garantisce l'esclusione reciproca e la libertà di stallo, ma non l'equità. È (credo) il primo algoritmo di esclusione reciproca che utilizza solo letture e scritture normali in grado di sincronizzare N processori in O (1) in assenza di contese. (Quando c'è contesa, ricade su un test O (N).) Dà una dimostrazione informale che il meglio che puoi fare nel caso senza contesa sono sette accessi alla memoria. (Dekker e Peterson lo fanno entrambi con 4, ma possono gestire solo 2 processori, quando estendi i loro algoritmi a N devono aggiungere un ulteriore accesso O (N).)

In tutto: direi che l'algoritmo di Dekker stesso è interessante principalmente da una prospettiva storica. L'articolo di Dijkstra ha spiegato l'importanza del problema dell'esclusione reciproca e ha dimostrato che poteva essere risolto. Ma con molti anni di senno di poi sono state trovate soluzioni più semplici (e più efficienti) di quelle di Dekker.


3
>> Nessuno dei due algoritmi è esente da fame o equo. Quello non è vero. L'algoritmo di Peterson è esente da fame e giusto. Se un thread si trova nella sezione critica e l'altro è in attesa nel loop di attesa, quello in attesa entrerà nel CS successivo, anche se il thread che era nel CS è molto più veloce.

Vorrei sottolineare che l'algoritmo di Peterson è privo di fame e giusto , anche solo per ripetere il commento di user24190. Non riesco a capire perché dopo tutti questi anni, l'autore di questa risposta non abbia né risposto al commento né corretto la sua risposta. (assicurati di chiamarmi dopo aver corretto la risposta in modo da poter rimuovere questo mio commento.)
Apass.Jack

Link per l'acquisto di Peterson "Miti del problema mutua esclusione": doi.org/10.1016/0020-0190(81)90106-X
Strager

PDF di "Miti sul problema dell'esclusione reciproca" di Peterson (Archive.org): web.archive.org/web/20150501155424/https://cs.nyu.edu/~lerner/…
strager

3

Nel seguente documento diamo modelli formali per gli algoritmi di Peterson e Dekker (e alcuni altri) e abbiamo usato il modello di controllo per dimostrare le loro proprietà. Per favore, trova i nostri risultati nella tabella qui sotto (le colonne "Deadlock" e "Divergent" si riferiscono ai nostri modelli, "ME" = TRUE significa che l'algoritmo è corretto, "Sorpasso" = TRUE significa che è giusto).

R. Meolic, T. Kapus, Z. Brezočnik. ACTLW - Una logica dell'albero di calcolo basata sull'azione con operatore a meno che. Scienze dell'informazione, 178 (6), pagg. 1542-1557, 2008.

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

inserisci qui la descrizione dell'immagine


1

L' algoritmo di Peterson ha una pressione più severa sull'entrare nella sezione critica, dove l' algoritmo di dekker è relativamente più morbido e meno aggressivo. Per renderlo più chiaro, diamo un'occhiata a un esempio sulla cultura iraniana. Prima di entrare in questo esempio, è bene sapere che le persone iraniane hanno un comportamento molto delicato l'una con l'altra mentre entrano da qualche parte! Immagina che due uomini iraniani entreranno in una casa e quella casa ha solo una porta per entrare.

Ora immagina due uomini di un'altra cultura (cultura zombiana ) a cui in realtà non si preoccupano troppo l'uno dell'altro mentre entrano da qualche parte ( È una questione di rispetto chiedere a qualcuno se vuole entrare o no ).

Per chiarire le informazioni sul problema possiamo dire che:

  • Due iraniani = Due processi che utilizzano l'algoritmo Dekker
  • Two Zombians = Due processi che utilizzano l'algoritmo Peterson

Quindi scopriamo cosa viene fatto in ogni algoritmo ( cultura ). I seguenti commenti sono per il primo uomo iraniano che sta per entrare nella casa mentre usa l' algoritmo 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

Abbiamo anche due zombi che entreranno nella casa usando l' algoritmo Peterson . Questo va come segue:

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

È importante ricordare che entrambi non entreranno all'interno mentre l'altro lo sta facendo ( mutua esclusione ), ma il popolo iraniano è molto più morbido.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.