PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme...

48
PROGRAMMATION MULTI-TÂCHES (MULTITHREADING)

Transcript of PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme...

Page 1: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

PROGRAMMATION MULTI-TÂCHES(MULTITHREADING)

Page 2: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 2

OBJECTIFS• Comprendre comment un programme peut être

fragmenté et exécuté en parallèle.

• Apprendre à implanter de tels programmes.

• Comprendre les principes de compétition (race) et d’inter-blocages (deadlocks).

• Apprendre à éviter le problème de corruption d’objets en utilisant les méthodes synchronisées.

• Utiliser la programmation multi-tâches pour faire des animations.

Page 3: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 3

CODES

• Souhait.java• CompteBanqueThread.java• SelectionThread.java

Page 4: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 4

Tâches légères (Threads)

• Une tâche légère est un processus léger correspondant à l’exécution d’un petit programme, ou d’une routine d’un programme plus gros, indépendamment de celui-ci.

• La machine virtuelle de Java (JVM) exécute les tâches légères d’un tel programme en allouant de petits fragments de temps à chacun.

– Cette façon de faire donne l’impression d’une exécution en parallèle des tâches légères (multithreads).

Page 5: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 5

Étapes pour exécuter des tâches légères

• Il faut implanter une classe qui étend (extends) la classe Thread.

• Placer le code d’une tâche dans la méthode run de votre classe.

• Créer un objet de votre classe. • Appellez la méthode start de votre classe pour

démarrer la tâche. • Quand un objet Thread est démarré, son code

est exécuté dans une nouvelle tâche légère.

Page 6: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 6

Envoyer des souhaits !

• Un programme qui imprime un souhait a chaque seconde pour 10 secondes :

public class SouhaitThread extends Thread {

public void run() { // les actions du thread . . . } // déclarations des variables utilisées par les actions du thread

. . . }

Page 7: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 7

L’action de la tâche pour SouhaitThread

• Imprimer le temps

• Imprimer le souhait

• Attendre une seconde

Page 8: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 8

SouhaitThread

On va chercher le temps avec un objet de type Date :Date maintenant = new Date();

Pour attendre une seconde, on peut utiliser la méthode sleep de la classe Thread :

sleep(millisecondes);

Une tâche légère qui dort peut générer une exception de type InterruptedException • On peut attraper cette exception• Faire le nécessaire le cas échéant

Page 9: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 9

La méthode run de SouhaitThread

public run() { try { //action }catch (InterruptedException exception) { //faire ce qu’il faut faire dans ce

cas }

}

Page 10: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 10

Allons voir le code de SouhaitThread.java…

Page 11: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 11

Pour démarrer la tâche

• Construire un objet de la classe SouhaitThread

SouhaitThread t =

new SouhaitThread(“Allô le

monde!");

• Lancer la méthode run avect.start();

Page 12: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 12

Allons voir le code de SouhaitThreadTest.java…

Page 13: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 13

Synchronisation des tâches

• La synchronisation des tâches (task scheduler) exécute chaque tâche pour un court moment, qu’on appelle une tranche de temps.

• Après avoir alloué une tranche de temps à une tâche, une autre tâche exécutable est choisie et sa tranche accordée.

• Une tâche est exécutable si elle n’est pas endormie (asleep) ni bloquée.

• L’ordre d’exécution des tâches n’est pas garantie.

Page 14: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 14

Terminaison des tâches…

• Une tâche termine quand sa méthode run termine.

• Il n’est pas conseillé de terminer une tâche avec la méthode stop.

• Plutôt, notifier la terminaison d’une tâche avec

t.interrupt();

Page 15: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 15

Terminaison des tâches

• La méthode run d’une tâche devrait vérifier occasionnellement si elle a été interrompue :• Utiliser la méthode isInterrupted.• Normalement, une tâche interrompue doit

relâcher ses ressources et sortir.• La méthode sleep lance l’exception InterruptedException même si la tâche interrompue est endormie.

• Dans tous les cas, attraper l’exception et terminer la tâche.

Page 16: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 16

Terminer une tâche

public void run() { try {

for(int i = 1; i <= REPETITIONS && !isInterrupted(); i++) {

//action}

} catch (InterruptedException exception) {

} //Sortie}

Page 17: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 17

Données corrompues par des tâches mal synchronisées

• Quand des tâches différentes partagent un objet commun, elles peuvent entrer en conflit.

• Dans l’exemple qui suit, un DepotThread et un RetraitThread manipulent un seul objet CompteBanque.

Page 18: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 18

Méthode run de DepotThread

public void run() { try { for(int i = 1; i <= REPETITIONS && !isInterrupted(); i++) { compte.depot(montant); sleep(DELAI); } } catch (InterruptedException exception) { } }

Page 19: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 19

Application

• Créer un objet CompteBanque.

• Créer un DepotThread t0 pour déposer $100 dans le compte 100 fois.

• Créer un RetraitThread t1 pour retirer $100 du compte 100 fois.

• Le résultat à la fin devrait être zéro,…

mais pas toujours !!!

Page 20: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 20

Scénario pour expliquer ce phénomène

• La tâche t0 exécute les instructions System.out.print("Dépôt " + montant); double nouvelleBalance = balance + montant;

• t0 atteint la fin de sa tranche de temps et…• t1 prend le contrôle… • t1 appelle la méthode retrait qui retire $100 de

la variable balance.

• La balance est de -$100 plutôt que $0 !!!• t1 s’endore…

Page 21: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 21

Scénario du phénomène (suite)• t0 reprend le contrôle et continue là où il a laissé.

• t0 exécute les lignes : System.out.println(", nouvelle balance " + nouvelleBalance); balance = nouvelleBalance;

• La balance est maintenant $100 plutôt que $0 parce que la méthode depot utilise la vieille version (une copie locale) de balance.

• La corruption des données est causée par la compétition des codes pour les traiter, en anglais le terme “race condition” est utilisé.

Page 22: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 22

“Race condition”

• Survient quand la mise à jour de données dépend de l’ordre de synchronisation de plusieurs tâches.

• Il est possible qu’une tâche soit arrêtée (sa tranche de temps terminée) en plein milieu d’un énoncé !

– Par exemple, elle peut évaluer le côté droit d’une assignation sans avoir le temps de stocker le résultat dans la variable de gauche de l’énoncé. L’assignation pourrait être complétée seulement lors de sa prochaine reprise d’exécution et tranche de temps alloué.

Page 23: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 23

Corruption du champ balance

Page 24: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 24

Allons voir le code de CompteBanqueThread.java…

Page 25: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 25

Solution au problème de compétition

• Une tâche doit être capable de bloquer temporairement un objet.

• Quand une tâche a le contrôle d’un objet, aucune autre tâche ne peut modifier l’état de cet objet.

• En Java, on utilise les méthodes synchronisées.• On marque les méthodes contenant du code

pouvant corrompre des données avec le mot clé synchronized.

Page 26: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 26

Méthodes synchronisées

public class CompteBanque { public synchronized void depot(double montant) { . . . }

public synchronized void retrait(double montant) { . . . } . . .}

Page 27: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 27

Méthodes synchronisées• En déclarant que les méthodes depot et retrait sont

synchronisées :

o Notre programme roulera correctement.

o Seulement une tâche à la fois pourra exécuter ses méthodes sur un objet donné, comme le compte de banque dans l’exemple.

o Quand une tâche démarre une de ses méthodes, elle est assurée de la complétion du code de cette méthode avant qu’une autre tâche puisse en prendre le contrôle, en exécutant l’une de ses méthodes synchronisées.

Page 28: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 28

Méthodes synchronisées

• En exécutant une méthode synchronisée :

o La tâche bloque l’objet.

o Aucune autre tâche ne peut bloquer ou modifier un objet déjà bloqué avant que la tâche qui l’a bloqué termine.

Page 29: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 29

Visualisation de tâches synchronisées • Imaginez un line-up à la salle de bain…• Les tâches sont les personnes. • Si la salle de bain est vide, une personne peut entrer.• Si une 2ième personne trouve la salle de bain barrée,

elle doit attendre jusqu’à ce qu’elle se libère.• Si plusieurs personnes veulent aller à la salle de

bain, elles doivent toutes attendre.• Les personnes ne forment pas nécessairement une

file d’attente ordonnée.• Une personne choisie au hasard peut avoir accès

quand la salle de bain devient disponible.

Page 30: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 30

Blocage (deadlock)

• Un blocage survient si aucune tâche ne peut procéder parce que chaque tâche est en train d’attendre qu’une autre fasse quelque chose d’abord.

• Dans l’exemple du compte de banque… public synchronized void retrait(double montant) { while(balance < montant) //attendre que la balance augmente . . . }

Page 31: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 31

Blocage

• Cette méthode peut mener à un blocage.• La tâche peut dormir et attendre que la balance

augmente mais c’est elle qui bloque le compte. • Aucune autre tâche ne peut exécuter la méthode

synchronisée de dépôt.• Si une tâche appelle depot, elle bloque jusqu’à ce que

retrait relâche le compte.• Mais retrait ne peut relâcher le compte tant que des

fonds supplémentaires ne sont pas déposés.• BLOCAGE !

Page 32: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 32

Éviter les blocages

• La méthode wait relâche temporairement un objet bloqué et désactive la tâche.

• Salle de bain…o On ne veut pas qu’une personne dans la

salle de bain s’endorme parce qu’il n’y a plus de papier !

o Imaginez que la personne abandonne et quitte la salle de bain.

o Cela permet à une autre personne d’entrer et de mettre du papier !

Page 33: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 33

Méthode retrait pour éviter le blocage

public synchronized void retrait(double montant) throws InterruptedException { while(balance < montant) wait();}

Page 34: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 34

Wait et NotifyAll• Une tâche qui appelle wait est dans un état

bloqué.

• Elle ne sera pas activée jusqu’à ce qu’elle soit débloquée.

• Elle débloque lorsqu’une autre tâche appelle notifyAll.

• Quand une tâche appelle notifyAll, toutes les tâches qui attendent l’objet sont débloquées.

• Seulement la tâche bloquant l’objet peut appeller notifyAll.

Page 35: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 35

Salle de bain wait/notifyAll

• La tâche appellant “wait” correspond à la personne qui entre dans la salle de bain et qui réalise qu’il n’y a plus de papier.

• La personne dans ce cas quitte la salle de bain et attends à l’extérieur.

• D’autres personnes peuvent entrer et sortir mais la première personne attend.

• Éventuellement, un préposé entre dans la salle de bain, met du papier et informe les autres personnes que le papier a été installé.

• Toutes les personnes qui attendaient peuvent maintenant compétitioner pour la salle de bain.

Page 36: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 36

Allons voir le code de CompteBanqueThreadTest.java…

Page 37: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 37

Animation

• Des animations contiennent différents objets qui bougent et changent dans le temps.

• La programmation multi-tâches est utile dans ce cas.

• Un algorithme d’animation aide à visualiser les étapes de l’exécution d’un algorithme (par exemple).

Page 38: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 38

Algorithme d’animation

• On exécute avec une tâche séparée la mise à jour d’une image reflétant l’état courant d’exécution d’un algorithme.

• La tâche fait une pause pour que l’usager constate le changement.

• Après un court délai, la tâche se réveille et exécute jusqu’au prochain point d’intérêt.

• Elle met à jour à nouveau l’image et fait une nouvelle pause…

Page 39: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 39

Animation du tri par sélection• Les éléments des états de l’algorithme sont :

o Le tableau des valeurs o La taille de la région triéeo L’élément courant

• Pour visualiser l’algorithme, il faut :o Montrer la partie triée du tableau en utilisant une

couleur différente. o Marquer l’élément courant avec la couleur rouge.

Page 40: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 40

Animation du tri par sélection

• Ajouter un Applet à la classe de l’algorithme :

public class Selection {

public Selection(int[] tableau, Applet unApplet) { t = tableau; applet = unApplet; } . . . private Applet applet; }

Page 41: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 41

Animation du tri par sélection• Fournir une méthode pause qui permet de dormir

une période de temps proportionnelle au nombre d’étapes requis, une unité de temps pour chaque visite d’un élément du tableau.

public void pause(int etapes) throws InterruptedException { if(Thread.currentThread().isInterrupted()) throw new InterruptedException();

applet.repaint(); Thread.sleep(etapes * DELAI);

}

Page 42: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 42

Animation du tri par sélection• Ajouter une méthode draw pour dessiner

l’état courant du tableau :

public void draw(Graphics2D g2) { int dX = applet.getWidth() / t.length; for(int i = 0; i < t.length; i++) { if(i == positionCourante) g2.setColor(Color.red); else if(i <= dejaTrie) g2.setColor(Color.blue); else g2.setColor(Color.black); g2.draw(new Line2D.Double(i * dX, 0, i * dX, t[i])); }}

Page 43: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 43

Animation du tri par sélection

• Ajouter une pause pour la méthode positionMinimum :

public int positionMinimum(int depart) throws InterruptedException {

int positionPlusPetite = depart; for(int i = depart + 1; i < t.length; i++) { if(t[i] < t[positionPlusPetite]) positionPlusPetite =

i; positionCourante = i; pause(2); } return positionPlusPetite;}

• Ajouter une pause similaire à la méthode tri.

Page 44: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 44

Applet pour le GUI• Démarrer l’animation en pressant le bouton de la souris. Si une

animation exécute déjà, interrompre la tâche pour la terminer.

public class SelectionApplet extends Applet { public SelectionApplet() { class MousePressListener extends MouseAdapter { public void mousePressed(MouseEvent e) { if(animation != null && animation.isAlive()) animation.interrupt(); demarrerAnimation(); } }

MouseListener auditeur = new MousePressListener(); addMouseListener(auditeur); . . . animation = null; } . . . private Thread animation;}

Page 45: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 45

Applet pour le GUI

• La méthode paint de l’Applet appelle la méthode draw de l’algorithme.

public void paint(Graphics g) { if (tri == null) return; Graphics2D g2 = (Graphics2D)g; tri.draw(g2); }

Page 46: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 46

Applet pour le GUI

• L’Applet contient une méthode demarrerAnimation

oElle construit un objet Selection, avec un nouveau tableau, qui réfère à l’Applet

oElle construit une tâche

oLa méthode run de la tâche appelle la méthode tri de Selection.

Page 47: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 47

Applet pour le GUI•

demarrerAnimation public void demarrerAnimation() { class AnimationThread extends Thread { public void run() { try { sel.tri(); } catch (InterruptedException exception) { } } }

int[] t = Tableau.tableauAleatoire(30, 300); sel = new Selection(t, this); animation = new AnimationThread(); animation.start();}

Page 48: PROGRAMMATION MULTI-TÂCHES (MULTITHREADING). IFT10202 OBJECTIFS Comprendre comment un programme peut être fragmenté et exécuté en parallèle. Apprendre.

IFT1020 48

Allons voir le code de SelectionApplet.java…