Processus et concurrence

Documents pareils
Synchro et Threads Java TM

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

Threads. Threads. USTL routier 1

Un ordonnanceur stupide

Introduction : les processus. Introduction : les threads. Plan

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Notion de thread (1/2)

Cours de Systèmes d Exploitation

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Une introduction à la technologie EJB (2/3)

INITIATION AU LANGAGE JAVA

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Introduction à la programmation concurrente

Programmation d Applications Concurrentes et Distribuées (INF431)

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Problèmes liés à la concurrence

4. Outils pour la synchronisation F. Boyer, Laboratoire Lig

On appelle variable condition une var qui peut être testée et

Programmer en JAVA. par Tama

Corrigé des exercices sur les références

Communication inter-processus (IPC) : tubes & sockets. exemples en C et en Java. F. Butelle

TD2 Programmation concurrentielle

Programmation Objet Java Correction

Premiers Pas en Programmation Objet : les Classes et les Objets

Exercices INF5171 : série #3 (Automne 2012)

Programme Compte bancaire (code)

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

SugarCubes. Jean-Ferdinand Susini Maître de Conférences, CNAM Chaire systèmes enfouis et embarqués. Paris, le 9 janvier, 2009

Auto-évaluation Programmation en Java

Plan du cours. Historique du langage Nouveautés de Java 7

Programmation Par Objets

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Programmation avec des objets : Cours 7. Menu du jour

Projet gestion d'objets dupliqués

Projet de programmation (IK3) : TP n 1 Correction

TD3: tableaux avancées, première classe et chaînes

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Programmation Orientée Objet - Licence TIS CM8/9. Rappel sur la séance précédente. Lancelot Pecquet Lancelot.Pecquet@math.univ-poitiers.

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

Modèle à composants. Daniel Hagimont. IRIT/ENSEEIHT 2 rue Charles Camichel - BP TOULOUSE CEDEX 7. Remerciements

Introduction aux systèmes temps réel. Iulian Ober IRIT

Pour plus de détails concernant le protocole TCP conférez vous à la présentation des protocoles Internet enseignée pendant.

INF 321 : mémento de la syntaxe de Java

Java DataBaseConnectivity

LOG4430 : Architecture et conception avancée

Développement Logiciel

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Package Java.util Classe générique

Gestion distribuée (par sockets) de banque en Java

Programmation par les Objets en Java

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

TP, première séquence d exercices.

Ordonnancement temps réel

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Cours 2: Exclusion Mutuelle entre processus (lourds, ou légers -- threads)

4. Outils pour la synchronisation F. Boyer, Laboratoire Sardes

Remote Method Invocation Les classes implémentant Serializable

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

PIGOURIER Vincent ANNEE SPECIALE 99/00 RAPPORT DE PROJET : LES THREADS JAVA. Responsable : Serge Rouveyrol

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Objets et Programmation. origine des langages orientés-objet

as Architecture des Systèmes d Information

Les processus légers : threads. Système L3, /31

RMI le langage Java XII-1 JMF

TP1 : Initiation à Java et Eclipse

PROGRAMMATION PAR OBJETS

Java Licence Professionnelle CISII,

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Apprendre la Programmation Orientée Objet avec le langage Java (avec exercices pratiques et corrigés)

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

Remote Method Invocation (RMI)

Calcul Parallèle. Cours 5 - JAVA RMI

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Dis papa, c est quoi un bus logiciel réparti?

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Le MSMQ. Version 1.0. Pierre-Franck Chauvet

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

TP Composants Java ME - Java EE. Le serveur GereCompteBancaireServlet

Chapitre 10. Les interfaces Comparable et Comparator 1

LOG4430 : Architecture logicielle et conception avancée

IRL : Simulation distribuée pour les systèmes embarqués

API04 Contribution. Apache Hadoop: Présentation et application dans le domaine des Data Warehouses. Introduction. Architecture

Introduction au langage Java

Sixième partie. Programmation multi-activités Java & Posix Threads. Généralités Java Threads POSIX Threads Autres approches

La JVM. La machine virtuelle Java. La JVM. La JVM

Introduction aux Systèmes et aux Réseaux

Les Threads. Sommaire. 1 Les Threads

Java Licence Professionnelle CISII,

La carte à puce. Jean-Philippe Babau

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Noyau de concurrence par moniteur pour Java ou C# pour une autre sémantique plus fiable et plus performante

Une introduction à Java

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Java 1.5 : principales nouveautés

Flux de données Lecture/Ecriture Fichiers

NFP 121. Java et les Threads. Présentation : Thierry Escalarasse Mai 2007

I-JVM: une machine virtuelle Java pour l isolation de composants dans OSGi

Support de cours Java

École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel. Cours INF2610. Contrôle périodique.

Transcription:

Concurrence (1/2) Inf 431 Cours 10 Processus et concurrence Les programmes séquentiels exécutent séquentiellement leurs instructions ils ne font qu une seule chose à la fois Mais il faut : jeanjacqueslevynet secrétariat de l enseignement: Catherine Bensoussan cb@lixpolytechniquefr Aile 00, LIX, 01 69 33 34 67 programmer des machines multi-processeurs; (Cray ; Thinking Machines ; Deep Blue ; Blue Gene ; gros serveurs) gérer des événements asynchrones lents ; (entrée au terminal, signaux d un capteur, etc) s adapter au comportement concurrent des humains ; wwwenseignementpolytechniquefr/informatique/if gérer les systèmes multi-utilisateurs ; réduire les délais d attente ; et aller plus vite 1 Création de processus 2 Terminaison Plan Concurrence (2/2) x = 3; y = 25; peut s exécuter en parallèle x = 3; y = 25; sur deux processeurs x = 3; y = x; ne s exécute pas en parallèle dépendances entre les deux instructions 3 Variables partagées 4 Atomicité et sections critiques 5 Interblocage 6 Famine 7 Synchronisation par variables de condition sur une machine vectorisée, on exécute en une seule instruction for (int i = 0; i < 100; ++i) a[i] = b[i] + c[i]; parallélisation des programmes automatique ou manuelle concurrence parallélisme concurrence = programmation concurrente + synchronisation parallélisme = optimisation des programmes pour aller plus vite parallélisme supercalculateurs

Processus (1/6) Un processus (Thread) est un programme qui s exécute class Code implements Runnable { Systemoutprintln ("Bonjour de " + ThreadcurrentThread()); Code p = new Code(); Thread t1 = new Thread(p); Thread t2 = new Thread(p); t1start(); t2start(); Exécution En Java Processus (3/6) l interface Runnable contient la méthode run() qui sera le point d entrée appelé par le lancement d un processus ( main mais moins standardisé pour lui passer des arguments) le constructeur Thread(p) crée un processus à partir d un objet Runnable le lancement d un processus se fait en appelant sa méthode start() dans l exemple précédent, il y a 3 processus : celui qui exécute le programme principal lancé par la JVM; t 1 et t 2 qui exécutent le même code p currentthread est une variable statique de la classe Thread donnant le processus courant Threadyield est facultatif (mais aide l ordonnanceur) Processus (2/6) Processus (4/6) Un processus (Thread) est un programme qui s exécute Le même exemple en programmation par objets class Code implements Runnable { class Code1 extends Thread { Systemoutprintln ("Bonjour de " + ThreadcurrentThread()); Threadyield(); Code p = new Code(); Thread t1 = new Thread(p); Thread t2 = new Thread(p); t1start(); t2start(); Exécution Systemoutprintln ("Bonjour de " + this); Threadyield(); Thread t1 = new Code1(); Thread t2 = new Code1(); t1start(); t2start(); Exécution Plus simple, mais moins de latitude dans la hiérarchie des classes

Processus (5/6) Terminaison (1/3) class Exemple1 implements Runnable { Les trois processus fonctionnent en parallèle; main t 1 t 2 try { Systemoutprintln ("Bonjour de " + ThreadcurrentThread()); Threadsleep(1000); catch (InterruptedException e) { Si moins de 3 processeurs, il faut partager l utilisation des processeurs (temps partagé) : main Thread t = new Thread(new Exemple1()); tstart(); tinterrupt(); t 1 Un processus t est souvent un programme qui ne s arrête jamais t 2 On peut l interrompre : t doit alors gérer sa propre terminaison Ainsi les invariants sont préservés Processus (6/6) Terminaison (2/3) les threads sont des processus légers (light-weight processes) les processus (lourds) sont les processus gérés par le système d exploitation (Unix, Linux, Windows) En Unix, on obtient leur liste par la commande ps, ps aux, top, les processus légers sont gérés par un sous-système : ici l interpréteur de programmes Java (la JVM) class Exemple2 extends Thread { while (!isinterrupted()) { Systemoutprintln ("Bonjour de " + this); ils sont légers car basculer d un processus à un autre est une opération peu couteuse (changement de contexte rapide) ici, comme nous ne nous soucions pas du système, nous les appelons simplement processus l exécution des processus est gérée par un ordonnanceur (scheduler), qui donne des tranches de temps à chaque processus, aussi équitablement que possible Thread t = new Exemple2(); tstart(); tinterrupt(); Exécution Un processus teste périodiquement s il n est pas interrompu Exemples de cercles (Boussinot, ENSMP Sophia) : 1 2 3 4 5

Terminaison (3/3) Variables partagées (2/2) class Exemple3 extends Thread { Systemoutprintln ("Bonjour de " + this); public static void main (String[ ] args) throws InterruptedException { Thread t = new Exemple3(); tstart(); tjoin(0); Exécution on ne peut prédire l ordre dans lequel P 1 ou P 2 écrira la variable partagée x cet ordre peut changer entre deux exécutions du même programme les programmes concurrents sont non déterministes On peut attendre la fin d un processus en précisant un délai maximum d attente en argument de join en millisecondes (0 = délai infini) La méthode join lance une exception si un autre processus a interrompu le processus courant Variables partagées (1/2) Atomicité et sections critiques (1/5) Une même variable x peut être modifiée par deux processus class P1 extends Thread { Px = 23; Threadyield(); class P2 extends Thread { Px = 7; Threadyield(); l écriture d un scalaire sur 32 bits est atomique ; l écriture d un entier long ou d un flottant double ne l est pas les expressions ne sont pas atomiques sens de i = 2; x[i] = i+3; ++i;?? ou pour un système de réservations de places class P { static int x = 0; class Avion extends Thread { static final int NBMAXSIEGES = 100; static boolean[ ] estoccupe = new boolean[nbmaxsieges]; public static void main (String[ ] args) throws InterruptedException { Thread t1 = new P1(), t2 = new P2(); t1start(); t2start(); Systemoutprintln (x); // Valeur de x? Threadsleep (1000); Exécution for (int i = 0; i < NBMAXSIEGES; ++i ) if (!estoccupe[i] ) { estoccupe[i] = true; reserverlesiege(i); Exécution static void reserverlesiege (int i) { Systemoutprintln (i);

Atomicité et sections critiques (2/5) Atomicité et sections critiques (4/5) Une section critique rend atomique un ensemble d instructions, on peut ainsi régler le problème de la réservation de places : class Avion extends Thread { static final int NBMAXSIEGES = 100; static boolean[ ] estoccupe = new boolean[nbmaxsieges]; public synchronized void run () { for (int i = 0; i < NBMAXSIEGES; ++i ) if (!estoccupe[i] ) { estoccupe[i] = true; reserverlesiege (i); static void reserverlesiege (int i) { Systemoutprintln (i); Le qualificatif synchronized contrôle l accès à une section critique le processus qui appelle une méthode synchronized doit obtenir un verrou sur l objet auquel elle appartient si le verrou est déjà pris par un autre processus, l appel est suspendu jusqu à ce que le verrou soit disponible en Java, les verrous sont associés aux objets Une seule méthode synchronized peut être appelée simultanément sur un même objet Mais une même méthode peut être appelée simultanément sur deux objets différents une méthode static synchronized fonctionne avec un verrou associé à toute la classe synchronized n existe que pour les méthodes et non pour l accès à un champ de données remarque : un processus, possédant déjà un verrou, peut le reprendre sans se bloquer ( Threads Posix) une méthode synchronized récursive ne se bloque pas Atomicité et sections critiques (3/5) Atomicité et sections critiques (5/5) par exemple pour modifier plusieurs données (composites) en maintenant des invariants class ComptesBancaires { private int comptea, compteb; synchronized void transfertversb (int s) { comptea = comptea - s; compteb = compteb + s; La somme des deux comptes doit rester constante, même si les appels de la méthode transfertversb sont faits dans deux processus distincts Les sections critiques fonctionnent en exclusion mutuelle Le qualificatif synchronized fonctionne aussi sur une instruction class ComptesBancaires { private int comptea, compteb; void transfertversb () { synchronized (this) { comptea = comptea - s; compteb = compteb + s; L argument de synchronized est l objet sur lequel on prend le verrou Cette forme de section critique permet de faire une section critique plus finement que sur des appels de méthodes Elle permet aussi un style moins programmation par objets

Interblocage Conditions (1/7) Créer des sections critiques demande un peu d attention, puisque des interblocages (deadlocks) sont possibles class P1 extends Thread { synchronized (a) { synchronized (b) { P 1 prend le verrou sur a, P 2 prend le verrou sur b, interblocage class P2 extends Thread { synchronized (b) { synchronized (a) { Détecter les interblocages peut être très complexe (absence d interblocages terminaison des programmes) Exercice 1 Faire un exemple d interblocage avec des appels sur des méthodes synchronisées Paradigme de la concurrence la file d attente concurrente Pour simplifier supposons la file f d au plus de longueur 1 ajouter et supprimer s exécutent de manière concurrente static synchronized void ajouter (int x, FIFO f) { if (fpleine) // Attendre que la file se vide fcontenu = x; fpleine = true; static synchronized int supprimer (FIFO f) { if (!fpleine) // Attendre que la file devienne pleine fpleine = false; return fcontenu; Famine Conditions (2/7) Rien ne garantit qu un processus bloqué devant une section critique passera un jour dans la section critique Famine (starvation) On suppose souvent que la politique d ordonnancement est juste et garantit de donner la main un jour à tout processus qui l a demandée (fair scheduling) Problème de l équité Equité faible : si un processus est prêt à s exécuter continument, il finira par s exécuter Equité forte : si un processus est prêt infiniment à s exécuter, il finira par s exécuter Parfois on veut le garantir logiquement en forçant un ordre de passage entre processus (cf cours suivant) ajouter doit attendre que la file f se vide, si f est pleine supprimer doit attendre que la file f se remplisse, si f est vide il faut relacher le verrou pour que l autre puisse s exécuter 2 solutions : ressortir de chaque méthode sans se bloquer et revenir tester la file attente active (busy wait) qui coûte cher en temps atomiquement relacher le verrou + attendre sur une condition en Java, une condition est une simple référence à un objet (son adresse) Par exemple, ici la file elle-même f quand on remplit la file, on peut envoyer un signal sur une condition et réveiller un processus en attente sur la condition

Conditions (3/7) Conditions (5/7) static void ajouter (int x, FIFO f) throws InterruptedException { synchronized (f) { while (fpleine) f fcontenu = x; fpleine = true; fnotify(); synchronized void ajouter (int x) throws InterruptedException { while (pleine) contenu = x; pleine = true; notifyall(); static int supprimer (FIFO f) throws InterruptedException { synchronized (f) { while (!fpleine) f fpleine = false; fnotify(); return fcontenu; Exécution synchronized int supprimer () throws InterruptedException { while (!pleine) pleine = false; notifyall(); return contenu; Exécution wait et notify sont deux méthodes de la classe Object Tous les objets ont donc ces deux méthodes présentes si plus de deux processus sont en jeu, on peut utiliser la méthode notifyall de la classe Object pour envoyer un signal à tous les processus en attente sur la condition Conditions (4/7) Conditions (6/7) synchronized void ajouter (int x) throws InterruptedException { while (pleine) contenu = x; pleine = true; notify(); notify n a pas de mémoire On réveille un quelconque des processus en attente sur la condition l action relachant le verrou et de mise en attente engendrée par wait est atomique Sinon, on pourrait perdre un signal émis par notify avant d attendre sur la condition synchronized int supprimer () throws InterruptedException { while (!pleine) pleine = false; notify(); return contenu; Exécution de même notify est fait avant de relâcher le verrou il faut utiliser un while et non un if dans la section critique En effet, il se peut qu un autre processus soit réveillé et qu il invalide le test Version plus en programmation par objets

Conditions (7/7) class FIFO { int debut, fin; boolean pleine, vide; int[ ] contenu; synchronized void ajouter (int x) throws InterruptedException { while (pleine) contenu[fin] = x; fin = (fin + 1) % contenulength; vide = false; pleine = fin == debut; notifyall(); synchronized int supprimer () throws InterruptedException { while (vide) int res = contenu[debut]; debut = (debut + 1) % contenulength; vide = fin == debut; pleine = false; notifyall(); return res; Exécution Exercices Exercice 2 Donner un exemple précis où notifyall fait une différence avec notify Exercice 3 Expliquer dans le détail pourquoi l action notify doit se faire en section critique Que se passerait-il si l instruction était faite en dehors de la section critique? Exercice 4 Faire l exemple de la file d attente avec la représentation en liste d éléments Exercice 5 Programmer des piles concurrentes Exercice 6 Montrer que le réveil des processus n est pas forcément dans l ordre premier en attente, premier réveillé Exercice 7 Donner un exemple où un processus peut attendre un temps infini avant d entrer en section critique Exercice 8 Comment programmer un service d attente où les processus sont réveillés dans l ordre d arrivée