CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La...

23
CSI2520, Hiver 2007 Programmation concurrente

Transcript of CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La...

Page 1: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Programmation concurrente

Page 2: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Programmation concurrente

• La programmation est distribuée lorsque les processus ne partagent pas la mémoire

• Sinon la programmation est dite parallèle

Page 3: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Processus

• Un processus ou tâche est une instance d'un programme ou d' une partie d' un programme pouvant être exécuté de façon autonome

• Un langage de programmation concurrente doit permettre:– la création de processus: des processus concurrents peuvent être créés à

partir de n' importe quel langage en utilisant de mécanismes explicites de programmation concurrente

– la synchronisation de leurs opérations:• Synchronisation coopérative: lorsqu' un processus attend la fin de l’exécution

d' un autre avant de poursuivre son exécution.• Synchronisation compétitive: lorsque plusieurs processus utilise la même

ressource. Il faut alors disposer d' un mécanisme d’exclusion mutuelle afin d’éviter que les processus interfèrent entre eux

– la communication des données entre processus: en utilisant des mécanismes de communication inter-processus définis par le système d’exploitation

Page 4: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Fil d’exécution

• Un fil d’exécution (thread) est une séquence d’exécution pouvant ou non interagir avec d’autres fils

• Les fils partagent souvent les même variables• Les fils ont souvent (mais pas nécessairement) une durée de vie

limitée• Un fil peut être bloqué:

– Si il désire utiliser des variables partagées avec d’autres fils– Si il doit attendre des résultats d’un autre fil

• Une application se subdivise en processus et un processus peut être composé de fils

• Les processus sont généralement créés lors de la conception de l’architecture alors que les fils sont créés lors de la phase de programmation

Page 5: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Fils en C++

• En utilisant – AfxBeginThread(fonction,parametre);

• Le paramètre est un pointeur à des void

• La fonction transmise a comme signature– UINT fonction(LPVOID connectionP);

Page 6: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple

class CMyThread{ ...public:  static UINT ThreadProc( LPVOID param ); private:  UINT DoThreadJob();};

UINT CMyThread::ThreadProc( LPVOID param ){  // Get the "this" pointer  CMyThread * pThis =     reinterpret_cast<CMyThread *>(param);   // Route to non-static member function  return pInstance->DoThreadJob();}

  

 UINT CMyThread::DoThreadJob(){  // ... Can call member functions here}  // Instance of the thread classCMyThread myThread; AfxBeginThread(   CMyThread::ThreadProc,   reinterpret_cast<LPVOID>( &myThread));

Page 7: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Fils en Java

public class HelloRunnable implements Runnable {

public void run() { System.out.println("Hello from a thread!"); }

public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); }

}

public class HelloThread extends Thread {

public void run() { System.out.println("Hello from a thread!"); }

public static void main(String args[]) { (new HelloThread()).start(); }

}

Page 8: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Contrôle des fils

HelloThread thread = HelloThread Fil();   

thread.start();   // demarrer le fil d’execution

thread.sleep( 3000 );   // mettre un fil en pause

thread.isAlive(); // verifier si un fil est actif

thread.interrupt();   // interrompre un fil

thread.join(); // attendre la terminaison d’un fil

Page 9: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exempleclass Example extends Thread { volatile boolean stop = false; public static void main( String args[] ) throws Exception { Example2 thread = new Example2(); System.out.println( "Starting thread..." ); thread.start(); Thread.sleep( 3000 ); System.out.println( "Asking thread to stop..." ); thread.stop = true; Thread.sleep( 3000 ); System.out.println( "Stopping application..." ); System.exit( 0 ); } public void run() { while ( !stop ) { System.out.println( "Thread is running..." ); sleep( 1000 ); } System.out.println( "Thread exiting under request..." ); }}

Page 10: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Niveaux de concurrence

• au niveau des énoncés: une série d' énoncés sont exécutés de façon concurrente, le processus principal suspend alors son exécution. Chacun des processus ainsi créés partagent le même ensemble de données (OpenMP)

• au niveau des sous-programmes: un processus commande alors la création d’un autre processus dont la tâche consiste à exécuter un certain sous-programme. Une fois le processus lancé, le processus appelant continue son exécution. Un mécanisme de synchronisation doit toutefois être disponible.

• au niveau des objets: chacune des instances d' une classe devient une entité concurrente; il y a alors exécution concurrente d' une de ses méthodes. Les attributs ne sont pas partagés.

• au niveau des programmes: ceci se produit lorsqu' un processus parent a la capacité de lancer un ou plusieurs processus enfant. Il doit toutefois exister un moyen de connaître l' identité d' un processus. Les données peuvent être partagées ou non.

Page 11: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Type de concurrence

• Physique: lorsque plusieurs processeurs se partagent les différents processus

• Logique: lorsque plusieurs processus se partagent le temps d' exécution sur un seul processeur.

• Distribué: lorsque plusieurs machines constituées en réseau se partagent les processus.

Page 12: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Moniteur

• Un moniteur est une abstraction qui contient les données partagées ainsi que les procédures qui accèdent à ces données

• La synchronisation est alors réalisée implicitement en n’autorisant qu’un accès à la fois au moniteur

• Lorsque le moniteur est occupé, tous les processus en attente pour accès sont placés dans une file

• En réalisant un appel à une opération du moniteur, un processus obtient des droits exclusifs d' accès aux ressources du moniteur. Cette exclusivité demeure jusqu’à ce que l’opération soit complétée ou jusqu’à ce que ce processus se place en attente

Page 13: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Java et moniteurs

• En Java, tous les objets ont un moniteur intrinsèque associé– Méthodes synchronisées– Blocs synchronisés

• avec l’énoncé synchronized(object)

• La file d’attente est gérée par la machine virtuelle Java

• Jusqu’à 50 fois plus lente que les méthodes non-synchronisées

Page 14: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple: un bassin d’objetsprotected Object[] items = ... whatever kinds of items being managedprotected boolean[] used = new boolean[MAX_AVAILABLE];

protected synchronized Object getNextAvailableItem() { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (!used[i]) { used[i] = true; return items[i]; } } return null; // not reached }

protected synchronized boolean markAsUnused(Object item) { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (item == items[i]) { if (used[i]) { used[i] = false; return true; } else return false; } } return false; } }

Page 15: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple: Le producteur/consommateur

 private LinkedList list = new LinkedList();

  public void produce() {    int len = 0;    synchronized(list) { // impose un verrou sur la liste      Object justProduced = new Object();      list.addFirst(justProduced);      len = list.size();      list.notifyAll(); // avise les autres fils    } // libere le verrou    System.out.println("List size now " + len);  }

Page 16: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple: Le producteur/consommateur public void consume() {    Object obj = null;    int len = 0;    synchronized(list) {      while (list.size() == 0) {        try {          list.wait(); // suspend le fil        } catch (InterruptedException ex) {          return;        }      }      obj = list.removeLast();      len = list.size();    }    System.out.println("Consuming object " + obj);    System.out.println("List size now " + len);  }

Page 17: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Sémaphore

• Une sémaphore est un mécanisme qui permet la synchronisation et le partage de ressource entre processus

P(Semaphore s) // Acquire Resource {

wait until s > 0, then s := s-1;} V(Semaphore s) // Release Resource {

s := s+1; } Init(Semaphore s, Integer v) { s := v; }

Page 18: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Mutex

• Un mutex permet de verrouiller une ressource pendant qu’un fil y accède

• Un mutex est donc associé à une ressource (une classe)

• Implementés en utilisant des sémaphore binaires

Page 19: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple C++

CMutex mutex; // this is the Mutex class

// This is the synchronization class // when you need to control access // to one resource using a given mutex CSingleLock mulock(&mutex);

if (mulock.Lock(1000)) { // will block until // the Mutex is available

// exclusive access to this block conteneur.erase(id);}

mulock.Unlock(); // release the Mutex

Page 20: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple: Accès exclusif à un fichier

CMutex mutex; // one attribute // of the class void reader() {

CSingleLock mulock(&mutex);

if (mulock.Lock(1000)) {

// do something… read_file();

}

mulock.Unlock(); }

void writer() {

CSingleLock mulock(&mutex);

if (mulock.Lock(1000)) {

// do something… write_file();

}

mulock.Unlock(); }

Page 21: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple: Accès à un fichier

• Lecture partagée– Il y a un nombre

maximum de fils pouvant lire

• Écriture exclusive– Un seul fil doit écrire à

la fois– Le fil écrivant doit

attendre que tous les fils lisant terminent

import java.util.concurrent.Semaphore const int MaxReaders = 32; Semaphore semaphore(MaxReaders); // MaxReaders is the total number of permits void ReaderThread::run() { semaphore.acquire(); // Acquires a permit from this semaphore, // blocking until one is available; read_file(); semaphore.release(); // Release a permit } void WriterThread::run() // should be synchronized // if more than one writer { for (int i = 0; i < MaxReaders; ++i) semaphore.acquire(); // acquisition graduelle de ressource write_file(); semaphore.release(MaxReaders); // Release all permits }

Page 22: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Attention aux ‘deadlocks ’ !

• Se produit lorsque deux fils vérouillent chacun une ressource et veulent aussi accéder à la ressource de l’autre– Ex: Le diner des philosophes

Page 23: CSI2520, Hiver 2007 Programmation concurrente. CSI2520, Hiver 2007 Programmation concurrente La programmation est distribuée lorsque les processus ne.

CSI2520, Hiver 2007

Exemple

class Attention {

public synchronized void ceci(Attention obj) {

... obj.cela(this); }

public synchronized void cela(Attention obj) {

… } }