Synchronisation

Jean-Michel Adam - Florian Rodriguez

1. Principe général : rendez-vous

  • Une tâche doit pouvoir :
    • activer une autre tâche ;
    • se bloquer (attendre) ou éventuellement bloquer une autre tâche ;
    • débloquer une ou même plusieurs tâches.
  • Caractérisation des mécanismes de synchronisation
    • déblocages mémorisés ou non
    • mécanismes directs ou indirects.

2. Mécanismes de synchronisation

  • Mécanismes directs
    • bloque(tâche) : endort la tâche désignée
    • dort() : endort la tâche courante
    • réveille(tâche) : réveille la tâche désignée
  • Mécanismes indirects
    • Synchronisation par objets communs, à travers des primitives protégeant les accès concurrents.
    • Synchronisation par sémaphore privés
      • 1 seule tâche peut exécuter acquire sur ce sémaphore
      • il est initialisé à 0 pour être toujours bloquant

3. Synchronisation par événements

  • Un événement à deux états : signalé ou non signalé (survenu ou non)
  • Manipulation par deux primitives:
    • attendre(e) : bloque la tâche courante si l'événement n'est pas signalé
    • signaler(e) : débloque une tâche en attente sur l'événement
  • Ces deux primitives sont exécutées en exclusion mutuelle

4. Synchronisation par événements

class Evenement {
  private boolean signal = false;
  private queue attente = new queue();

  attendre() {
      if(!signal)
          dormir();
  }
  signaler() {
    signal = true;
    if(!attente.estVide())
        reveiller(attente.defiler());
  }
  r_a_z() {
      signal = false;
  }
}

5. Rendez-vous par événements

  • T1 : … RDV(); …
  • T2 : … RDV(); …
  • Tn : … RDV(); …
  • Comment écrire RDV?
int i = 0;
Evenement e = new Evenement();
e.r_a_z();

RDV() {
      i++;
      if(i == n)
              e.signaler();
      else
              e.attendre();
}

Pb: accès concurrent à i!

6. Rendez-vous par événements

  • T1 : … RDV(); …
  • T2 : … RDV(); …
  • Tn : … RDV(); …
  • Comment écrire RDV?
int i = 0;
Evenement e = new Evenement();
e.r_a_z();
mutex.init_semaphore(1);

RDV() {
      mutex.acquire();
      i++;
      if(i == n)
          mutex.release();
          e.signaler();
      else
          mutex.release();
          e.attendre();

}

7. Les moniteurs

  • Classe avec des propriétés particulières
    • on n’a accès qu’aux primitives publiques, les variables sont privées
    • les procédures sont exécutées en exclusion mutuelle et donc les variables privées sont manipulées en exclusion mutuelle
    • on peut bloquer et réveiller des tâches. Le blocage et le réveil s’expriment au moyen de conditions.

8. Les moniteurs

  • Exemple de moniteur
class Condition {
  private queue attente = new queue();
  attendre() {
      attente.enfiler(tâcheCourante);
      dormir();
  }
  signaler() {
      if(!attente.estVide())
          reveiller(attente.defiler());
  }
  estVide() {
      return attente.estVide();
  }
}

9. RDV avec un moniteur

  • T1 : … RDV.Arriver(); …
  • T2 : … RDV.Arriver(); …
  • Tn : … RDV.Arriver(); …
  • Comment écrire RDV?
class RDV() {
    private int i;
    private int n;
    private Condition c = new Condition();

    public RDV(int nbtâches) { //constructeur
      i = 0;
      n = nbtâches;
    }

    public synchronized void Arriver() {
        i++;
        if(i < n)
            c.attendre();
        else
            c.signaler(); // Réveil en cascade
    }

}