Title: Programmation concurrente
1Programmation concurrente
2Programmation concurrente
- La programmation est distribuée lorsque les
processus ne partagent pas la mémoire - Sinon la programmation est dite parallèle
3Processus
- 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 lexé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 dexclusion
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
dexploitation
4Fil dexécution
- Un fil dexécution (thread) est une séquence
dexécution pouvant ou non interagir avec
dautres 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 dautres fils - Si il doit attendre des résultats dun 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 larchitecture alors que les fils
sont créés lors de la phase de programmation
5Fils 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)
6Exemple
class CMyThread  ... public   static UINT
ThreadProc( LPVOID param )  private  UINT
DoThreadJob() UINT CMyThreadThreadProc(
LPVOID param ) Â // Get the "this" pointer Â
CMyThread pThis    reinterpret_castltCMyThrea
d gt(param) Â Â // Route to non-static member
function  return pInstance-gtDoThreadJob()  Â
 UINT CMyThreadDoThreadJob()  // ... Can
call member functions here   // Instance of
the thread class CMyThread myThread  AfxBeginThr
ead( Â CMyThreadThreadProc, Â
reinterpret_castltLPVOIDgt( myThread))
7Fils 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("He
llo from a thread!") public static
void main(String args) (new
HelloThread()).start()
8Contrôle des fils
HelloThread thread HelloThread
Fil()Â Â Â thread.start()Â Â Â // demarrer le fil
dexecution 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 dun fil
9Exemple
class 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..." )
10Niveaux 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 dun 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.
11Type 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.
12Moniteur
- 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 nautorisant quun 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
lopération soit complétée ou jusquà ce que ce
processus se place en attente
13Java 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 dattente est gérée par la machine
virtuelle Java - Jusquà 50 fois plus lente que les méthodes
non-synchronisées
14Exemple un bassin dobjets
protected Object items ... whatever kinds of
items being managed protected boolean used
new booleanMAX_AVAILABLE protected
synchronized Object getNextAvailableItem()
for (int i 0 i lt MAX_AVAILABLE i)
if (!usedi) usedi true return itemsi
return null // not reached
protected synchronized boolean
markAsUnused(Object item) for (int i 0
i lt MAX_AVAILABLE i) if (item
itemsi) if (usedi) usedi
false return true else return false
return false
15Exemple Le producteur/consommateur
 private LinkedList list  new LinkedList()  pu
blic void produce()     int len  0    synchro
nized(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.o
ut.println("List size now "  len) Â
16Exemple Le producteur/consommateur
 public void consume()     Object obj  null Â
  int len  0    synchronized(list)       whil
e (list.size()  0)         try           lis
t.wait() // suspend le fil         catch (Inter
ruptedException ex)           return       Â
            obj  list.removeLast()      lenÂ
 list.size()        System.out.println("Consum
ing object "  obj)    System.out.println("ListÂ
size now "  len) Â
17Sé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 gt 0, then s s-1
-
- V(Semaphore s) // Release Resource
-
- s s1
-
- Init(Semaphore s, Integer v) s v
18Mutex
- Un mutex permet de verrouiller une ressource
pendant quun fil y accède - Un mutex est donc associé à une ressource (une
classe) - Implementés en utilisant des sémaphore binaires
19Exemple 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.Unloc
k() // release the Mutex
20Exemple 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()
21Exemple Accès à un fichier
import java.util.concurrent.Semaphore
const int MaxReaders 32 Semaphore
semaphore(MaxReaders) // MaxReaders is the
total number of permits void
ReaderThreadrun()
semaphore.acquire() // Acquires a permit from
this semaphore,
// blocking until one is available
read_file() semaphore.release() //
Release a permit void
WriterThreadrun() // should be synchronized
// if
more than one writer for (int i
0 i lt MaxReaders i) semaphore.acquire()
// acquisition graduelle de ressource
write_file()
semaphore.release(MaxReaders) // Release all
permits
- 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
22Attention aux deadlocks !
- Se produit lorsque deux fils vérouillent chacun
une ressource et veulent aussi accéder à la
ressource de lautre - Ex Le diner des philosophes
23Exemple
class Attention public synchronized
void ceci(Attention obj) ...
obj.cela(this) public
synchronized void cela(Attention obj)