Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [Teorico] Algoritmo di dekker

    Salve a tutti,
    su wikipedia ho trovato il seguento algoritmo di dekker:

    codice:
    // dichiarazione delle variabili globali comuni
    boolean flag0 = false, flag1 = false;
    int turno = 0; // oppure: int turno = 1;
    
    // processo #0
    // ...
    P:   flag0 = true;
         while (flag1) { // busy waiting
            if (turno == 1) {
               flag0 = false;
               goto P;
            }
         }
         // <sezione critica>
         flag0 = false;
         turno = 1;
    // ...
    
    // processo #1
    // ...
    P:   flag1 = true;     
         while (flag0) { // busy waiting
            if (turno == 0) {
               flag1 = false;
               goto P;
            }
         } 
         // <sezione critica>
         flag1 = false;
         turno = 0;  
    // ...
    Non riesco bene a capirlo, ovvero, a che serve la variabile turno? non basterebbe utilizzare il flag?
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  2. #2
    Perchè da quello che ho capito non basta solo il flag a mantenere il programma in busy waiting? Anche perchè se mettiamo il caso che siamo nel processo 0, il turno è 1, ma il processo 1 non sta lavorando e quindi flag1 è false, il processo 0 si avvierà alla sua sezione critica.
    Nel mentre se si avvia il processo 1, avremo comunque flag0 a true e quindi entreremo in busy waiting, però il turno rimarrà uguale ad 1 quindi non sarà mai valido quell'if e continuerà comuqnue ad attendere.

    Dov'è che il mio ragionamento toppa?
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  3. #3
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    (chiedo scusa se mi dilungherò un po')

    L'algoritmo di Wikipedia (in italiano) mi sembra scritto male. Quel goto P non ha senso: se il processo 0 trova che il processo 1 ha il flag impostato a true e che il turno è suo (cioè del processo 1), non deve ritentare di entrare in sezione critica (quindi quel goto P non deve esserci), ma deve attendere che la variabile turno sia impostata a 0, per poi ritentare di entrare in sezione critica. Chiaramente lo stesso vale dal punto di vista del processo 1.

    Ti consiglio di vedere l'algoritmo nella versione inglese di Wikipedia

    http://en.wikipedia.org/wiki/Dekker%...thm#Pseudocode

    In sostanza, se il processo i vede che la variabile turno è impostata proprio ad i, sa di poter "insistere" a entrare nella sezione critica e non si ferma nel ciclo while() "a vuoto", continuando quindi a verificare il valore del flag dell'altro processo.

    Se non ci fosse la variabile turno, ma solo le due variabili "flag", l'algoritmo sarebbe come questo

    (tratto da "Sistemi operativi", W. Stallings)

    codice:
    P0:
    
      flag[0] = true;
      while (flag[1]) {
        flag[0] = false;
        /* breve pausa */
        flag[0] = true;
      }
      <sezione critica>
      flag[0] = false;
      <resto del programma>
    
    P1:
    
      flag[1] = true;
      while (flag[0]) {
        flag[1] = false;
        /* breve pausa */
        flag[1] = true;
      }
      <sezione critica>
      flag[1] = false;
      <resto del programma>
    che potrebbe essere anche una soluzione corretta, ma presenta un problema di fondo: non tiene conto del fatto che, nella progettazione di algoritmi di sincronizzazione, non si debba fare alcuna ipotesi sulla velocità relativa di esecuzione dei due processi. Potrebbe infatti accadere questo:

    P0 imposta flag[0] a true;
    P1 imposta flag[1] a true;
    P0 controlla flag[1];
    P1 controlla flag[0];
    P0 imposta flag[0] a false;
    P1 imposta flag[1] a false;
    --da capo--
    P0 imposta flag[0] a true;
    P1 imposta flag[1] a true;
    ...

    in sostanza, se i due processi eseguissero le istruzioni dell'algoritmo alternandosi strettamente, continuerebbero a farsi le cerimonie reciprocamente e nessuno di loro entrerebbe mai in sezione critica, della serie "prima tu P0", "no ma figurati, prima tu P1" e così, da un punto di vista teorico, potrebbero andare avanti all'infinito.

    Ora è chiaro che una situazione del genere, sul piano reale, è estremamente improbabile. Tuttavia il problema è che, da un punto di vista formale, questa soluzione fa un'ipotesi non legittima sulla velocità relativa dei processi, violando uno dei principi di base della problematica della sincronizzazione. Insomma probabilmente andrebbe quasi sempre bene, ma per essere valido l'algoritmo non può violare quello che è un assioma, un po' come se fosse un teorema di geometria.

    In conclusione, comunque, ti consiglio di dare un'occhiata all'algoritmo di Petterson, che "semplifica" l'algoritmo di Dekker, anzi secondo Tanenbaum (in "I moderni sistemi operativi") lo rende addirittura "obsoleto", al punto che quest'ultimo nel suo libro non lo descrive nemmeno, limitandosi ad un semplice accenno alla sua esistenza.

    Ti consiglio inoltre, se ne hai occasione, la lettura del succitato libro di Stallings per la parte relativa alla sincronizzazione dei processi: è spiegata in maniera eccellente a mio avviso, anche per quanto riguarda le soluzioni hardware e le primitive di sincronizzazione.

    Tra l'altro, l'algoritmo riportato su Wikipedia in inglese è praticamente lo stesso dello Stallings; quello della versione italiana non so da chi sia stato partorito, sinceramente.
    every day above ground is a good one

  4. #4
    Originariamente inviato da YuYevon
    (chiedo scusa se mi dilungherò un po')

    L'algoritmo di Wikipedia (in italiano) mi sembra scritto male. Quel goto P non ha senso: se il processo 0 trova che il processo 1 ha il flag impostato a true e che il turno è suo (cioè del processo 1), non deve ritentare di entrare in sezione critica (quindi quel goto P non deve esserci), ma deve attendere che la variabile turno sia impostata a 0, per poi ritentare di entrare in sezione critica. Chiaramente lo stesso vale dal punto di vista del processo 1.

    Ti consiglio di vedere l'algoritmo nella versione inglese di Wikipedia

    http://en.wikipedia.org/wiki/Dekker%...thm#Pseudocode

    In sostanza, se il processo i vede che la variabile turno è impostata proprio ad i, sa di poter "insistere" a entrare nella sezione critica e non si ferma nel ciclo while() "a vuoto", continuando quindi a verificare il valore del flag dell'altro processo.

    Se non ci fosse la variabile turno, ma solo le due variabili "flag", l'algoritmo sarebbe come questo

    (tratto da "Sistemi operativi", W. Stallings)

    codice:
    P0:
    
      flag[0] = true;
      while (flag[1]) {
        flag[0] = false;
        /* breve pausa */
        flag[0] = true;
      }
      <sezione critica>
      flag[0] = false;
      <resto del programma>
    
    P1:
    
      flag[1] = true;
      while (flag[0]) {
        flag[1] = false;
        /* breve pausa */
        flag[1] = true;
      }
      <sezione critica>
      flag[1] = false;
      <resto del programma>
    che potrebbe essere anche una soluzione corretta, ma presenta un problema di fondo: non tiene conto del fatto che, nella progettazione di algoritmi di sincronizzazione, non si debba fare alcuna ipotesi sulla velocità relativa di esecuzione dei due processi. Potrebbe infatti accadere questo:

    P0 imposta flag[0] a true;
    P1 imposta flag[1] a true;
    P0 controlla flag[1];
    P1 controlla flag[0];
    P0 imposta flag[0] a false;
    P1 imposta flag[1] a false;
    --da capo--
    P0 imposta flag[0] a true;
    P1 imposta flag[1] a true;
    ...

    in sostanza, se i due processi eseguissero le istruzioni dell'algoritmo alternandosi strettamente, continuerebbero a farsi le cerimonie reciprocamente e nessuno di loro entrerebbe mai in sezione critica, della serie "prima tu P0", "no ma figurati, prima tu P1" e così, da un punto di vista teorico, potrebbero andare avanti all'infinito.

    Ora è chiaro che una situazione del genere, sul piano reale, è estremamente improbabile. Tuttavia il problema è che, da un punto di vista formale, questa soluzione fa un'ipotesi non legittima sulla velocità relativa dei processi, violando uno dei principi di base della problematica della sincronizzazione. Insomma probabilmente andrebbe quasi sempre bene, ma per essere valido l'algoritmo non può violare quello che è un assioma, un po' come se fosse un teorema di geometria.

    In conclusione, comunque, ti consiglio di dare un'occhiata all'algoritmo di Petterson, che "semplifica" l'algoritmo di Dekker, anzi secondo Tanenbaum (in "I moderni sistemi operativi") lo rende addirittura "obsoleto", al punto che quest'ultimo nel suo libro non lo descrive nemmeno, limitandosi ad un semplice accenno alla sua esistenza.

    Ti consiglio inoltre, se ne hai occasione, la lettura del succitato libro di Stallings per la parte relativa alla sincronizzazione dei processi: è spiegata in maniera eccellente a mio avviso, anche per quanto riguarda le soluzioni hardware e le primitive di sincronizzazione.

    Tra l'altro, l'algoritmo riportato su Wikipedia in inglese è praticamente lo stesso dello Stallings; quello della versione italiana non so da chi sia stato partorito, sinceramente.
    Ma io ho visto proprio lo stallings e mi persiste proprio quel dubbio del turno.
    Ovvero, quella variabile turno che fa? dice "chi ha maggiore priorità" e se uno ha maggiore priorità e non c'è l'altro in esecuzione può essere eseguito? Cioè non mi è prorpio ben chiaro il cocnetto di funzionamento della variable turno per quanto abbia letto i vari passaggi presenti sullo stallings. Ho anche il tannenbaum ma se dici che non lo riporta nemmeno..
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Originariamente inviato da Neptune
    Ma io ho visto proprio lo stallings e mi persiste proprio quel dubbio del turno.
    Ovvero, quella variabile turno che fa? dice "chi ha maggiore priorità" e se uno ha maggiore priorità e non c'è l'altro in esecuzione può essere eseguito? Cioè non mi è prorpio ben chiaro il cocnetto di funzionamento della variable turno per quanto abbia letto i vari passaggi presenti sullo stallings.
    La variabile turno serve semplicemente a sopperire all'insufficienza dei soli due flag booleani. Con i soli flag, incorri nei problemi descritti nel secondo, terzo e quarto tentativo presentati in quel libro (rispettivamente: violazione della mutua esclusione, deadlock e "mutua cortesia", quello di cui dicevo nel post precedente, a causa dell'ipotesi illegittima sulla velocità relativa dei processi).

    Con la variabile turno, invece, se il processo 0 trova impostato a true il flag del processo 1 ma vede che il turno è il suo (cioè 0), non fa il cortese come nel "quarto tentativo" ma "reclama" il suo diritto a entrare in sezione critica, questo perché va immediatamente a ricontrollare la condizione del while su flag[1], come se dicesse: "è il mio turno, ti muovi a farmi entrare?". Se invece il turno è 1 e il flag del processo 1 è a true, allora 0 sa di avere torto a insistere e si mette in attesa attiva sul while finché il processo 1 non avrà impostato a 0 la variabile turno.

    Insomma "turno" serve a stabilire a chi spetta il diritto di accesso alla sezione critica per evitare che i processi si facciano le cerimonie. E' pur vero però che da sola la variabile sarebbe insufficiente, questo per il problema di stretta alternanza che si avrebbe nel caso del "primo tentativo", oltre che per il problema della starvation di uno dei due processi in caso di morte dell'altro in sezione critica.

    Ho anche il tannenbaum ma se dici che non lo riporta nemmeno..
    Io ho una versione un po' datata del Tanenbaum e a pag. 96 leggo

    Combinando l'idea dei turni con l'idea delle variabili di lock e di warning (avvertimento), un matematico olandese, T. Dekker, fu il primo a trovare una soluzione software al problema della mutua esclusione che non richiedesse l'alternanza stretta [...] Nel 1981, G. L. Peterson scoprì un algoritmo molto più semplice per garantire la mutua esclusione, rendendo obsoleto l'algirotmo di Dekker.
    e dopo procede appunto con la descrizione dell'algoritmo di Peterson. Se hai una versione più recente controlla che non sia diversa, anche se credo proprio di no.

    Del resto anche Stallings dice:

    L'algoritmo di Dekker risolve il problema della mutua esclusione con un programma piuttosto complesso: è difficile da seguire e la dimostrazione della correttezza è complessa. Peterson fornisce una soluzione semplice ed elegante [...]
    every day above ground is a good one

  6. #6
    Utente bannato
    Registrato dal
    Sep 2009
    Messaggi
    0
    Originariamente inviato da Neptune
    Ma io ho visto proprio lo stallings e mi persiste proprio quel dubbio del turno.
    Ovvero, quella variabile turno che fa? dice "chi ha maggiore priorità" e se uno ha maggiore priorità e non c'è l'altro in esecuzione può essere eseguito? Cioè non mi è prorpio ben chiaro il cocnetto di funzionamento della variable turno per quanto abbia letto i vari passaggi presenti sullo stallings. Ho anche il tannenbaum ma se dici che non lo riporta nemmeno..
    di la si chiedono che fine hai fatto...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.