Vous êtes sur la page 1sur 90

Dr.A.

Adouane 1
 Le modèle de processus décrit jusqu’ici est un programme qui
s’exécute selon un chemin unique avec un seul compteur
ordinal, On dit qu’il a un flot de contrôle unique ou un seul
thread.

 Les systèmes modernes offrent au processus une exécution


multi-threads, cela permet l’exécution simultanée des parties
d’un même processus

Dr.A.Adouane 2
 Le processus est vu comme étant un ensemble de ressources
(code exécutable, segments de données, de fichiers, de
périphériques, etc.)

 Les parties constituants le processus sont appelées flots de


contrôle ou processus légers (threads en anglais)

 En plus des ressources communes, chaque thread a sa propre


zone de données ou de variables locales, sa propre pile
d’exécution, ses propres registres et son propre compteur
ordinal

Dr.A.Adouane 3
 Les threads sont des processus légers exécutés à l’intérieur d’un
processus

 L’exécution des threads est concurrente

 Il existe toujours au moins un thread : le thread principal

 La durée de vie d’un thread ne peut pas dépasser celle du


processus qui l’a crée

 Les threads d’un même processus partagent la même mémoire

Dr.A.Adouane 4
Dr.A.Adouane 5
 Réactivité Le processus continue à s’exécuter même si
certaines de ses parties sont bloquées.

 Partage de ressources facilite la coopération, améliore la


performance

 Économie d’espace mémoire Les threads issues du même


processus utilise la même mémoire

 Économie de temps: Par exemple sous Solaris, la création d’un


processus est 30 fois plus lente que celle d’un thread

Dr.A.Adouane 6
• Si plusieurs processus problème d’accès !
• Un thread pour interagir avec l’utilisateur,
• Un thread pour reformater en arrière plan,
• Un thread pour sauvegarder périodiquement le
document

Dr.A.Adouane 7
 Serveur web sans threads: le serveur en attente récupère une
requête et la traite jusqu’à la fin avant de passer à une autre

Si la requête est bloquée en attente du disque, le serveur est


inactif mais ne peut
prendre d’autres
requêtes

Dr.A.Adouane 8
 Le Dispatcher thread se charge de réceptionner les requêtes.

 Il choisit, pour chaque requête reçue, un thread libre (en


attente d’une requête). Ce thread va se charger d’interpréter
la requête.

Dr.A.Adouane 9
 Tout comme les processus, les threads peuvent prendre
plusieurs états:
 Actifs : En cours d’exécution, qui utilise le processeur

 Bloqué : thread qui attend un événement pour se débloquer.


◦ Un thread qui lance un appel système pour récupéré une entrée au
clavier, il reste bloqué jusqu’à ce qu’on tape sur le clavier.
◦ Un thread peut également attendre qu’un autre thread le débloque.

 Prêt : Le thread est planifié pour l’exécution, il attend son tour

Dr.A.Adouane 10
Dr.A.Adouane 11
 Un thread inclut:

 Un compteur ordinal qui effectue le suivie des instructions à


exécuter

 Des registres qui détiennent ses variables de travail en cours

 Une pile qui contient l’historique de l’exécution

Dr.A.Adouane 12
 Les threads autorisent les exécutions multiples dans le même
environnement de processus

 Les threads se partagent un espace d’adressage, les fichiers


ouverts et les ressources, on dit qu’on fait du multithreading

 En comparaison, les processus se partagent la mémoire


physique, les disques et autres ressources

Dr.A.Adouane 13
Dr.A.Adouane 14
 Tout les threads ont le même espace d’adressage  ils ont
les même variables globales

 Chaque thread peut lire, écrire ou effacer la pile d’un autre


thread

 Les threads proviennent du même utilisateur  sont crée


pour coopérer entre eux  pas de nécessité de protection
entre threads

Dr.A.Adouane 15
 Chaque thread possède sa propre pile (Stack)

Dr.A.Adouane 16
 Les piles contiennent un bloc d’activation (Frame) pour
chaque procédure invoquée par le thread et qui n’a encore
rien retourné

 Le bloc d’activation contient les variables locales de la


procédure et l’adresse de retour après exécution

 Chaque thread appelle des procédure différentes  chaque


thread a besoin de sa propre pile

Dr.A.Adouane 17
 La majorité des systèmes permettent le multiflot
(multithreading). Ils sont offerts soit au niveau utilisateur, soit
au niveau noyau, on retrouve donc :

 Les threads utilisateur

 Les threads noyau

 Les threads combinés

Dr.A.Adouane 18
 Les threads utilisateur sont implantés dans une bibliothèque
(niveau utilisateur) qui fournit un support pour les gérer

 Ils sont portables sur différentes plate-formes (ne sont pas


gérés par le noyau).

 Ils sont gérés par une application.

 Le changement de contexte est rapide

Dr.A.Adouane 19
 Le noyau gère les processus (table des processus) et ne se
préoccupe pas de l’existence des threads (modèle plusieurs-
à-un).

 Lorsque le noyau alloue le processeur à un processus, le


temps d’allocation du processeur est réparti entre les
différents threads du processus (cette répartition n’est pas
gérée par le noyau).

Dr.A.Adouane 20
Dr.A.Adouane 21
 Les threads Java peuvent être créés en :
◦ dérivant la class Thread
◦ Implémentant l’interface Runnable

Plusieurs API pour contrôler les threads:


suspend() , sleep() , resume() , stop() , etc.

 Les threads Java sont gérés par la machine virtuelle Java


(JVM).

Dr.A.Adouane 22
 À tout instant, au plus un thread par processus est en cours
d’exécution.

 Cette implémentation n’est pas intéressante pour des systèmes


multiprocesseurs.

 Si un thread d’un processus se bloque, tout le processus est


bloqué.

 Pour pallier cet inconvénient, certaines librairies transforment les


appels système bloquants en appels système non bloquants.

Dr.A.Adouane 23
 Le thread utilisateur s’exécute au dessus d’un système d’exécution
(run time system) qui est une collection de procédures prenant en
charge les threads, et utilise les appels de fonction :

 Pthread_create: crée un nouveau thread

 Pthread_exit: termine le thread appelant

 Pthread_join: attendre la fin d’un thread

 Pthread_yield: libère l’UC pour laisser un autre thread s’exécuter

Dr.A.Adouane 24
 Chaque processus a sa propre table de threads, les informations
nécessaires au redémarrage d’un thread prêt ou bloqué y sont
stocké

 Si un thread est susceptible de se bloqué, il invoque une procédure


du système d’exécution (locale), si elle décide de le bloquer elle
stock ses registres dans la table des threads

 Elle regarde ensuite dans la table si un thread est prêt pour


l’exécution, et recharge les registres de ce nouveau thread

 Se type de basculement est plus rapide que le changement de


contexte des processus

Dr.A.Adouane 25
 Dans certains SE comme UNIX il est possible de prédire le
blocage de thread

 Un appel système appelé SELECT permet de savoir si un read


à venir donne un blocage

 La procédure Read est remplacer par Select, si le Select


s’exécute alors la procédure Read est invoqué

Dr.A.Adouane 26
 Si Select se bloque alors un autre thread est exécuter, quand il
fini on essaye encore le thread bloqué

 Ce système de prédiction est peu efficace et oblige à réécrire


des parties de la bibliothèque, mais n’a pas de remplacement

 Le code intervenant avant et après l’appel système pour cette


vérification est appelé code WRAPPER

Dr.A.Adouane 27
 Si un programme appelle une instruction qui ne se trouve pas en
mémoire, un défaut de page se produit, le SE cherche l’instruction
manquante dans le disque.

 Pendant ce temps le processus est bloqué

 Si un thread provoque le défaut de page, le noyau bloque le


processus dans son ensemble sans voir le thread et attend que
l’E/S disque finisse

 Cela pénalise le processus qui a peut être d’autre thread à exécuter


!

Dr.A.Adouane 28
 Sont directement supportés par le noyau du système
d'exploitation.

 Le système d'exploitation se charge de leur gestion, Un temps


CPU est alloué à chaque thread (modèle un-à-un)

 Si un thread d’un processus est bloqué, un autre thread du


processus peut être élu par le noyau

 Cette implémentation est plus intéressante pour les systèmes


multiprocesseurs.

Dr.A.Adouane 29
 Un processus peux ajuster les niveaux de priorité de ses
threads.

 Par exemple, un processus peut améliorer son interactivité en


assignant :
◦ une forte priorité à un thread qui traite les requêtes des utilisateurs
◦ une plus faible priorité aux autres.

Dr.A.Adouane 30
 Le noyau connait les threads et détient la table de threads
pour les suivre

 Lorsqu’un thread veut créer ou détruire un autre thread, il


effectue un appel noyau qui prend en charge la demande en
modifiant la table des threads

 Si un thread se bloque le noyau peut exécuter un autre thread


du même processus ou d’un autre processus

Dr.A.Adouane 31
Dr.A.Adouane 32
 La création et destruction de thread noyau est relativement
lourde

 Le recyclage de thread est utilisé pour diminuer cette charge

 Après la destruction d’un thread il est marqué non


exécutable, mais ses structures de données noyau ne sont pas
effacé

 Lorsqu’un thread doit être crée, un ancien thread est réactivé


pour réduire la charge CPU

Dr.A.Adouane 33
 Si un thread d’un processus déclenche un défaut de page, le
noyau peut facilement exécuter un autre thread du même
processus pendant que la page demandé est récupéré

Dr.A.Adouane 34
 Linux ne fait pas de distinction entre les processus et les
threads qui sont communément appelés tâches.

 Il implémente le modèle multiflot un-à-un.

 La création de tâches est réalisée au moyen de l’appel


système clone().

 Clone() permet de spécifier les ressources à partager (espace


d’adressage, fichiers, signaux..) entre les tâches créatrice et
créée

Dr.A.Adouane 35
 Inconvénients :

 Performance (gestion plus coûteuse)

 Les programmes utilisant les threads noyau sont moins portables que
ceux qui utilisent des threads utilisateur.

 Changement de contexte lent

 Dans le cas d’une interruption quel thread doit la traiter ?

 Si plusieurs threads veulent prendre cette interruption, comment choisir ?

Dr.A.Adouane 36
 Les avantages des threads noyau et utilisateur ont tenté d’être
combiné

 On emploie des threads noyau et on multiplexe plusieurs


threads utilisateur sur un thread noyau

 Le noyau ne connait que les threads noyau et les ordonnance

Dr.A.Adouane 37
 Le noyau ne connait que les threads noyau et les ordonnance

 Certains thread noyau peuvent disposer de threads utilisateur


multiplexé, ceux-ci sont crées, détruits et ordonnancés
exactement comme les threads utilisateurs

 Chaque threads noyau a un jeux de threads utilisateur

Dr.A.Adouane 38
Dr.A.Adouane 39
 Solaris 2 implémente le multiflot selon le modèle plusieurs-à-
plusieurs.

 Il distingue 3 niveaux de threads :


◦ Threads utilisateur,
◦ Processus poids léger (LWP)
◦ Threads noyau.

 Chaque LWP supporte un ou plusieurs threads utilisateur et


correspond à un thread noyau.

 Le noyau ordonnance les threads noyau.

Dr.A.Adouane 40
 Il fournit une bibliothèque contenant des API pour la création et la
gestion de threads utilisateur et des LWP.

 La bibliothèque se charge de :
◦ assigner un ou plusieurs LWP à un processus,
◦ multiplexer les threads utilisateur avec les LWP disponibles pour le processus.
◦ ajuster dynamiquement le nombre de LWP fournis au processus :

 Si tous les LWP sont bloqués et un thread est prêt à l’exécution, un


autre LWP sera fourni au processus pour exécuter ce thread.

 Les LWP inutilisés pendant un certain temps sont éliminés

Dr.A.Adouane 41
 Une application Win32 est composée d'un ou plusieurs processus.

 Un ou plusieurs threads fonctionnent dans le contexte du


processus.

 Un thread est l'unité de base à laquelle le système d'exploitation


assigne du temps de processeur.

 Un thread peut exécuter n'importe quelle partie du code de


processus, y compris celles actuellement exécuté par un autre
thread.

Dr.A.Adouane 42
 Une fibre est une unité d'exécution ordonnancée au niveau
utilisateur. Les fibres s’exécutent dans le contexte des threads
qui les ordonnancent (chaque thread peut avoir plusieurs
fibres).

 Un job permet à des groupes de processus d'être considérés


comme une unité.

 Les opérations exécutées sur un job affectent tous les


processus du job.

Dr.A.Adouane 43
 Linux ne fait pas de distinction entre les processus et les
threads.

 Un thread est un processus qui partage un certain nombre de


ressources avec le processus créateur : l'espace d'adressage,
les fichiers ouverts ou autres

 Pour la gestion Posix de threads, Linux utilise la bibliothèque


pthread, qui doit être appelée par l'éditeur de liens

Dr.A.Adouane 44
 thread : pour récupérer l‘identité du thread qui est crée

 attr : attributs du thread, Si attr est NULL, la valeur par défaut est prise

 fonction : fonction a exécuter en parallèle

 arg : arguments de la fonction

 Identite d'un thread : pthread_t pthread_self(void);

 Egalite ente threads :


int pthread_equal(pthread_t t1, pthread_t t2);

Dr.A.Adouane 45
 Création de threads :
 int pthread_create (pthread_t *thread ,
pthread_attr_t *attr,
void *nomfonction,
void *arg );

 Le service pthread_create() crée un processus léger qui exécute la


fonction nomfonction avec l'argument arg et les attributs attr.

 Les attributs permettent de spécifier la taille de la pile, la priorité, la


politique de planification

 L'appel renvoie 0 s'il réussit, sinon il renvoie une valeur non nulle
identifiant l'erreur qui s'est produite

Dr.A.Adouane 46
 Suspension de threads:

 int pthread_join(pthread_t *thid, void **valeur_de_retour);

 pthread_join() suspend l'exécution d'un processus léger


jusqu'à ce que se termine le processus léger avec
l'identicateur thid.

 Il retourne l'état de terminaison du processus léger.

Dr.A.Adouane 47
 Terminaison de threads:
 void pthread_exit(void *valeur_de_retour);

 pthread_exit() permet à un processus léger de terminer son


exécution

 Il retourne l'état de terminaison grâce à :

 int pthread_attr_setdetachstate(pthread_attr_t *attr,


int detachstate);

Dr.A.Adouane 48
 pthread_attr_setdetachstate() sert à établir l'état de
terminaison d'un processus léger :

 Si detachstate = PTHREAD_CREATE_DETACHED le processus


léger libérera ses ressources quand il terminera.

 Si detachstate = PTHREAD_CREATE_JOINABLE le processus


léger ne libérera pas ses ressources. Il sera donc nécessaire
d'appeler phtread_join()

Dr.A.Adouane 49
 Un thread peut annuler ou terminer l’exécution d’un autre thread
(pthread_cancel).

 int pthread_cancel (pthread_t thread);

 Cependant, les ressources utilisées (fichiers, allocations


dynamiques, verrous, etc) ne sont pas libérées.

 Il est possible de spécifier une ou plusieurs fonctions de nettoyage


à exécuter à la terminaison du thread
◦ pthread_cleanup_push()
◦ pthread_cleanup_pop()

Dr.A.Adouane 50
 Si le thread dont on demande l'arrêt possède un verrou et ne
l'a toujours pas relâché, il y a un risque de laisser ce verrou
dans l'état verrouillé, il sera alors dans ce cas impossible de le
récupérer, pour éviter cela on utilise:

 int pthread_setcancelstate (int state, int * etat_pred);

 Cette fonction permet de changer le comportement du thread


appelant par rapport aux requêtes d'annulations

Dr.A.Adouane 51
 Ces arguments sont dans l'ordre:

 Etat d'annulation. Il peut prendre les deux valeurs suivantes :


◦ PTHREAD_CANCEL_ENABLE : Autorise les annulations pour le thread appelant.
◦ PTHREAD_CANCEL_DISABLE : Désactive les requêtes d'annulation.

 Adresse vers l'état précédent (ou NULL) permettant ainsi sa


restauration lors d'un prochain appel de la fonction.

 La fonction renvoie la valeur 0 en cas de succès ou une erreur si


l'argument ne correspond ni à PTHREAD_CANCEL_ENABLE et ni
à PTHREAD_CANCEL_DISABLE

Dr.A.Adouane 52
 Le programme thread-pid.c montre l'implantation de threads
dans GNU/Linux, ainsi que la récupération du pid du thread

 Étant donné que aussi bien main() que la fonction_thread()


tournent tout le temps, cela nous permet de regarder de près
les détails de leur exécution.

 Le programme doit être compilé avec la librairie -lpthread

Dr.A.Adouane 53
Dr.A.Adouane 54
 L'exécution en tâche de fond de pthread-pid.c est :
 MonPc > gcc -o pthread-pid thread-pid.c -lpthread
 MonPc > pthread-pid &
 [1] 24133
 MonPc > pid de main = 24133
 pid du thread fils = 24136

Dr.A.Adouane 55
 On affiche les threads avec PS :

 MonPc> ps x
 PID TTY STAT TIME COMMAND
 23928 pts/2 S 0:00 -tcsh
 24133 pts/2 R 0:53 pthread-pid
 24135 pts/2 S 0:00 pthread-pid
 24136 pts/2 R 0:53 pthread-pid
 24194 pts/2 R 0:00 ps x

Dr.A.Adouane 56
 L’activation de l’ordonnanceur consistent à imiter le fonctionnement
des threads noyau avec les performances des threads utilisateur.

 Si un thread bloque sur un appel système ou un défaut de page, on


doit pouvoir exécuter un autre thread en état prêts

 Si un thread est bloqué par un autre il n’ai pas nécessaire de faire


intervenir le noyau

 Cela évite la perte de performances induite par la transition entre le


noyau et l’espace utilisateur

Dr.A.Adouane 57
 Le noyau affecte un certains nombre de processeurs virtuels à
chaque processus, c’est ensuite le système d’exécution qui alloue
les CPU au thread

 Les processeurs virtuels peuvent correspondres ou pas à de vrais


CPU dans le cas de multiprocesseur

 Un processus a initialement un processeur virtuel, il peut ensuite


en demander d’autre, comme il peut rendre des processeur si il
n’en a pas besoin

 Le noyau peut reprendre aussi des processeurs au besoin

Dr.A.Adouane 58
 Quand le noyau détecte un blocage de thread, il prévient le système
d’exécution du processus en envoyant à la pile le numéro du thread et
une description de l’erreur.

 Afin que la notification fonctionne le noyau doit activer le système


d’exécution à une adresse de départ connue, ce mécanisme est appelé
Upcal

 Quand ce mécanisme est activé, le système d’exécution marque ce


thread comme bloqué, il choisit ensuite un autre parmi les threads prêts.

 Lorsque le noyau voit que le thread bloqué peut s’exécuter, il effectue un


upcall pour prévenir le système qu’il peut reprendre l’exécution.

Dr.A.Adouane 59
 Dans le cas d’une interruption matérielle, le processeur concerné
bascule en mode noyau, le thread est bloqué, deux cas possible:

 L’interruption ne concerne pas le processus interrompu ( E/S d’un


autre processus), à la fin de l’interruption le thread est replacer
dans son état d’avant interruption.

 Si le processus est concerné par l’interruption ( arrivé d’une page


d’un de ces threads), le thread reste bloqué, le système
d’exécution reprend le processeur et choisit un thread, soit
reprendre l’interrompu soit un autre

Dr.A.Adouane 60
 Les threads sont très utilisé dans les systèmes distribués, comme
dans un serveur ou les threads sont bloqués en attente d’une
requête à traiter.

 On peut envisager les choses différemment, un nouveau thread


n’est crée qu’a l’arrivé de la requête, c’est ce qu’on appelle Thread
spontané (pop-up thread)

 Comme il s’agit d’un nouveau thread, il n’a pas d’historique (


registre, pile…) à restaurer, les threads sont neufs et vont donc
être crées très rapidement , le temps de latence est très court entre
l’arrivée du message et le début du traitement

Dr.A.Adouane 61
Dr.A.Adouane 62
 Afin de mettre en place les threads spontanés, il est
nécessaire de mettre en place une planification, pour choisir
par exemple où crée le nouveau thread ( utilisateur/noyau)

 Il est plus rapide et facile de crée le thread dans le noyau,


dans ce cas il peut facilement avoir accès au table du noyau et
aux périphériques E/S.

 Cette solution bien que rapide peut être risqué car un thread
qui bug dans le noyau peut causé beaucoup plus de problème
qu’un thread utilisateur.

Dr.A.Adouane 63
 La conversion d’un code monothread en multithread n’ai pas
chose facile, il faut pour cela respecter certaines règles.

 Un thread se compose en générale de plusieurs procédures,


elle peuvent t’avoir des variables locales, globales et des
paramètres.

 Les variables globales pour un threads peuvent ne pas l’être


pout tout le programme, elle sont dites globale car utilisé par
plusieurs threads, mais les autres threads ne peuvent pas les
modifier ( lecture seul)

Dr.A.Adouane 64
 Exemple: Dans Unix si un processus ou thread fait un appel
système qui n’aboutie pas, le code erreur généré est placé dans la
variable errno

 Le thread 1 demande accès à un fichier, la réponse est enregistré


dans errno, avant que thread 1 ne lit le contenu de errno son
temps d’exécution fini, il est donc suspendu.

 Un thread 2 est alors exécuté, ce dernier fait un appel qui échoue,


l’erreur est enregistré dans errno, et il se bloque.

 Le thread 1 est rechargé et va lire la valeur de errno, il y trouve la


mauvaise valeur et va avoir un comportement erroné.

Dr.A.Adouane 65
Dr.A.Adouane 66
 Plusieurs solution existe pour ce problème:

 la plus simple est d’interdire les variables globales,


malheureusement cette solution entraine beaucoup de conflit.

 On peut également donner à chaque thread sa propre variable


globale, dans ce cas là chaque thread a sa propre variable
errno, cela évite les conflits. Cela va crée un nouveau niveau
de variable, visibles par toutes les procédure du thread

Dr.A.Adouane 67
Dr.A.Adouane 68
 Cette solution n’ai pas aussi facile a appliquer, en effet les
langage de programmation ne prévoient pas ce nouveau
niveau de variable

 Il est possible de réserver une partie de mémoire aux


variables globales, et de la passer ensuite en paramètre aux
procédures de threads

Dr.A.Adouane 69
 Une solution plus lourde consiste à rajouter de nouvelle procédure
de bibliothèque pour crée, définir et lire ces variables globales
limitée aux threads :

 Create_global(’’ bufptr ’’) : avec cette appel, on alloue de la


mémoire au pointeur bufptr dans un segment mémoire ou dans
une zone de stockage réservé au thread

 Seule le thread appelant connais où se trouve sa variable globale,


si un autre thread crée une variable de même nom, elle aura un
emplacement diffèrent, on évite donc d’écraser la variable.

Dr.A.Adouane 70
 Afin d’accéder au variables on a besoin de deux appels pour
lire et écrire:

 Set_global(’’ bufptr ’’, &buf) : cet appel stocke la valeur d’un


pointeur à l’emplacement créé par « create_global »

 Bufptr = read_global(’’bufptr ’’) : retourne l’adresse stocké


dans la variable globale, on peut ainsi accéder au donnés
enregistré

Dr.A.Adouane 71
 Un autre problème se pose lors de la transformation vers le
multithreads, beaucoup de procédure de bibliothèque ne sont
pas réentrante ( réutilisable)

 Le problème se pose au moment où on a un deuxième appel


vers une procédure qui traite déjà un ancien appel en cours.

 Sous UNIX, la procédure d’allocation mémoire malloc


maintient les tables essentielles à l’utilisation de la mémoire

Dr.A.Adouane 72
 Pendant que malloc fait la mise à jour de ces listes, il peut y
avoir des pointeurs qui ne pointes nulle part.

 Si à ce moment là on a un basculement de thread, et que le


nouveau thread utilise un pointeur non valide cela conduira à
un arrêt du programme

 Une solution consiste à utiliser le code wrapper, on rajoute un


bit à la bibliothèque pour indiqué si elle est utilisé ou pas, si
un autre thread veut utiliser la même bibliothèque il sera
bloquée

Dr.A.Adouane 73
 Durant leurs exécution les threads peuvent utiliser des
signaux, des problèmes se posent également dans ce cas
pour la transformation vers le multithreads

 Si un thread appelle alarm, il est important que le résultat soit


envoyé au thread demandeur, hors le noyau ne voit pas ce
thread et ne peut donc pas lui envoyer la réponse

 Également si un processus à qu’une seul alarme et que


plusieurs de ses threads font des appels alarm en même
temps !

Dr.A.Adouane 74
 Également un autre problème est celui de la gestion de la pile.
En temps normal quand le noyau voit que le processus à une
pile qui déborde il l’augmente automatiquement.

 Dans le cas de multithread, le noyau ne réalise pas qu’il y a un


débordement de pile, pour lui il y a une erreur qu’il ne peut
pas résoudre automatiquement

Dr.A.Adouane 75
 Beaucoup de problèmes peuvent donc surgir au moment du
passage du monothreads au multithreads ce qui pose des
problème de compatibilité

 Ces problèmes bien que surmontable, montre qu’il n’ai pas


facile de faire une simple transformation pour passer au
multithreads

 Il faut repenser tout le système d’une manière multithreads de


façon à assurer la compatibilité des programmes existants

Dr.A.Adouane 76
 Pour permettre la description et l'analyse d'un système de
tâches, plusieurs représentations graphiques existe :

 le graphe de précédence

 les automates finis

 les réseaux de Pétri

Dr.A.Adouane 77
 Comme leur nom l’indique, les graphes de précédence
permettent de représenter les relations de précédence ( qui
précède l’autre) entre les taches

 Une tache est unité élémentaire de traitement ayant une


cohérence logique

Dr.A.Adouane 78
 Une relation de précédence sur un ensemble E est une relation
vérifiant les propriétés suivantes:

 1) Pour tout T de l'ensemble E, T < T est impossible

 2) Pour tout (T1, T2) de E x E, T1 < T2 et T2 < T1 est


impossible simultanément

 3) La relation < est transitive

Dr.A.Adouane 79
 Un système de tâches (E, <) est un ensemble E de tâches muni
d'une relation de précédence <

 (E, <) définit une relation d’ordre total



 Si T1 et T2 sont dépendants alors les parallélisés donne une
incohérence

 Si T1 et T2 ne sont pas dépendants alors ne pas les


parallélisés est une perte de temps

Dr.A.Adouane 80
 La concurrence donne lieu à deux modes d’exécution, soit les
processus sont parallèles soit il sont séquentiels

 Si il sont parallèles l’ordre d’exécution de T1 et T2 est


quelconque : T1 < T2 et T1 > T2

 Si il sont séquentiels par exemple T1< T2 alors T2 ne peux


pas commencer son exécution avant la fin de T1

Dr.A.Adouane 81
 Un système de tâches peut se représenter sous forme de
graphe orienté.

 Les sommets sont les tâches

 Les arcs représentent les relations de précédence entre les


tâches.

 Un arc de la tâche Ti vers la tâche Tj existe si et seulement si


Ti < Tj

Dr.A.Adouane 82
T1 T2 T3

 On peut voir sur ce graphe de précédence qu’il y a un ordre


d’exécution :
◦ T3 est le successeur de T2 qui lui-même est successeur de T1, T3 est dit
tache terminale

◦ T1 est dit prédécesseur de T2, qui lui est prédécesseur de T3

 Si Tx n'est ni successeur ni prédécesseur d'une tâche Ty, alors les


tâches Tx et Ty sont dites indépendantes

Dr.A.Adouane 83
 Règles de concurrence de Bernstein :
 Soit R(Ti) l’ensemble des variables lut par les processus, et
W(Ti) l’ensemble des variables modifié par les processus
 Deux taches Ti et Tj sont // si et seulement si :
◦ R(Ti) ∩ W(Tj) = Φ
◦ W(Ti) ∩ R(Tj) = Φ
◦ W(Ti) ∩ W(Tj) = Φ

 Si une règle n’ai pas validée, le parallélisme donne lieu à des


incohérences  soit Ti<Tj soit Tj<Ti

Dr.A.Adouane 84
 Il s'agit de représenter à travers un langage la mise en
séquence ou en parallèle des tâches d'un graphe de
précédence.

 La mise en séquence se note: SeqBegin T1; T2; T3 SeqEnd ( ou


directement Begin et End )

 La mise en parallèle se note: ParBegin T4; T5; T6 ParEnd

Dr.A.Adouane 85
 On utilise également :

 Fork() pour la parallélisassions dans le code

 Fork Ei la tâche est lancée en parallèle avec la tâche se trouvant sous


l’étiquette Ei

 Join n : permet d’attendre la fin d’exécution de n processus comme suit


 Join n
 Begin
◦ n--
◦ Si n≠0 exit
◦ Fsi
 End

Dr.A.Adouane 86
 Afin de pouvoir utiliser ces outils de programmation, il est
nécessaire de bien écrire les relations de parallélisme et
séquentiellement: T1 T2 T3

T4

T5

 Cela nous donne la notation T1//{(T2//T3).T4}.T5

Dr.A.Adouane 87
 T1//{(T2//T3).T4}.T5
 Begin T1 T2 T3
◦ Parbegin
◦ T1
◦ Begin
 Parbegin T4
 T2,T3
 Parend
 T4
◦ End T5
◦ Parend
◦ T5
 End

Dr.A.Adouane 88
 Begin
 n=2
T1 T2 T3
 m=2
◦ Fork (E2)
◦ Fork (E3)
◦ T1 goto E5
◦ E2 : T2 goto E4 T4
◦ E3: T3 goto E4
◦ E4: join n
 T4
◦ E5: join m
 T5 T5
 End

Dr.A.Adouane 89
 https://fr.wikipedia.org/wiki/Système_déterministe
 http://www.enseignement.polytechnique.fr/profs/informatiqu
e/Eric.Goubault/poly/cours002.html#SIMD
 http://www.groupes.polymtl.ca/inf2610/documentation/note
s/chap4.pdf
 http://www.di.ens.fr/~pouzet/cours/systeme/cours04/cours
-04.pdf
 http://www.groupes.polymtl.ca/inf3600/TransparentsAut200
6/Ch3INF3600.pdf
 Système d’exploitation, 3eme édition, Andrew tanenbaum.

Dr.A.Adouane 90

Vous aimerez peut-être aussi