• Aucun résultat trouvé

Licence 2 — I4b Semaines du 07/03 au 19/03/2005

N/A
N/A
Protected

Academic year: 2022

Partager "Licence 2 — I4b Semaines du 07/03 au 19/03/2005"

Copied!
5
0
0

Texte intégral

(1)

Licence 2 — I4b

Semaines du 07/03 au 19/03/2005

TP 1 & 2 • Cr´eation de processus : threads

Java fournit en standard un certain nombre de classes pour g´erer, les fenˆetres graphiques, les fichiers, le r´eseau, les processus etc. Cette derni`ere fonctionnalit´e est r´ealis´ee au moyen de la notion de thread (pr´esent´ee dans le chapitre III du cours). Un thread est un processus l´eger qui partage avec son parent l’ensemble de ses donn´ees. L’utilisation de plusieurs threads dans un programme permet : – d’´eviter les engorgements :avec un seul thread, le programme doit s’arrˆeter compl`etement pour attendre des processus lents commne la gestion des acc`es aux disques durs ou les commu- nications avec d’autres machines. Le programme est inactif jusqu’`a ce que ses demandes soit satisfaites. Avec plusieurs threads, l’application peut poursuivre l’ex´ecution des autres threads pendant que le thread qui attend le resultat d’un processus lent est bloqu´e ;

– d’organiser le comportement du programme :avec plusieurs threads on peut decomposer le programme en plusieurs sections ind´ependantes et assigner diff´erentes priorit´es `a chaque thread afin d’attribuer davantage de temps CPU aux tˆaches critiques ;

– d’utiliser plusieurs processeurs.

Dans ce TP on se propose d’´etudier la cr´eation de threads, l’affectation de priorit´e et les probl`emes d’echange et de partage de donn´ees entre plusieurs threads (concurrence).

Interactions de Java et du syst`eme d’exploitation

Java est une technologie d´efinie par SUN Microsystems `a la fin de l’ann´ee 1995. Java est plus qu’un langage de programmation, on parle courament de la plateforme Java. La plateforme Java s’articule autour de trois composants essentiels :

1. les sp´ecifications du langage de programmation Java ;

2. un ensemble d’interfaces/biblioth`eques de programmation d’applications (API) ; 3. une sp´ecification de machine virtuelle.

La langage Java fournit, en plus des aspects traditionnels les langages de programmation orient´es objets, un support de haut niveau pour la programmation r´eseau et la communication entre objets distribu´es. C’est ´egalement un langage multi-threads au sens ou un programme Java peut avoir plusieurs flots de contrˆole.

L’API Java contient une API de base et un extension standard. L’API de base fournit un sup- port simple pour le graphisme, les entr´ees sorties, les fonctions courantes et le r´eseau (java.lang, java.awt,java.io,java.net, etc.). Les extensions incluent des services sp´ecifiques pour le support d’applications d’entreprise (s´ecurit´e, interfaces bases de donn´ees etc.). Comme le langage ´evolue, de nombreux packages faissant partie des extensions sont inclus dans l’API de base.

La machine virtuelle JVM est une sp´ecification de machine abstraite constitu´ee d’un chargeur de classe et d’un interpr´eteur Java capable d’ex´ecuter le code objet (byte-code) produit par le com- pilateur javac. Le code objet est ind´ependant de la plateforme mat´erielle. Le chargeur de classes utilise les fichiers .classet les API pour permettre l’ex´ecution des programmes par l’interpr´eteur.

L’interpr`eteur peut ˆetre un logiciel qui interpr`ete instruction apr`es instruction les commandes du code objet ou un compilateur `a la vol´ee qui traduit en code machine le code objet (JIT Just-In- Time). Dans certains cas l’interpr`eteur Java peut ˆetre implant´e dans une puce sp´ecifique. Afin de pouvoir ex´ecuter un programme Java (.class) sur une architecture il faut disposer d’une machine virtuelle sp´ecifique `a cette architecture. Le probl`eme de portabilit´e des programme est donc simplifi´e puisqu’il suffit de porter la machine virtuelle (quelques Mo). La machine virtuelle r´ealise donc une

(2)

Programme Java fichiers .class

Système hote code objet byte code Chargeur de classes

Interpréteur Java

fichiers .classAPI Java

Fig. 1 – Principe de fonctionnement de la JVM

abstraction du syst`eme d’exploitation. Ainsi, on peut par g´en´eralisation consid´erer la JVM comme un syst`eme d’eploitation. Le processeur sur lequel est d´efinie la JVM est un processeur abstrait capable d’ex´ecuter du byte-code.

Un instance de la JVM est cr´eee chaque fois qu’une application Java est lanc´ee. L’instance de la JVM commence son ex´ecution lorsque la m´ethode main()est invoqu´ee. C’est ´egalement vrai pour les applets quia priori n’ont pas de m´ethode main puisque celle ci est g´er´ee par le navigateur. Si on lance n programmes Java sur une machine, il y auranmachines virtuelles en ex´ecution.

Linux Plateforme

Java ProgrammeJava

Plateforme Java ProgrammeJava

Plateforme Java ProgrammeJava

Plateforme Java ProgrammeJava

Windows MAC OS X Navigateur/UX

Fig. 2 – Portabilit´e de la JVM

L’environnement Java que vous allez utiliser en TP est compos´e du compilateur Java (javac) et de la machine virtuelle (java). Le principe de d´eveloppement du programme est d´ecrit `a la figure 1.

Il est d´econseiller d’utiliser NetBeans car vous aurez du mal `a visualiser les r´esultats produits lors de l’ex´ecution des programme. Vous devez ˆetre en mesure d’interpr`eter tous les r´esultats affich´es par les programmes que vous allez r´ealiser.

Exercice 1. Cr´ eation de threads

Au d´emarrage un seul thread est cr´ee. Pour en cr´eer un nouveau, il faut cr´eer un nouvel objet de la classeThreadpuis le d´emarrer c’est-`a-dire lui demander d’ex´ecuter une portion de code (m´ethode).

Il existe deux strat´egies. Soit le code `a ex´ecuter est sp´ecifi´e dans une classe qui h´erite de la classe Thread, soit il est sp´ecifi´e dans une classe qui impl´emente l’interface Runnable. Dans la seconde strat´egie, un objet sera pass´e en param`etre lors de la cr´eation du nouvel objet de la classeThread. La premi`ere solution a l’avantage de ne manipuler qu’un seul objet mais elle a l’inconv´enient d’interdire tout nouvel h´eritage.

Pour cr´eer la nouvelle thread il faut utiliser l’un des constructeurs de la classe Thread. Les plus courament utilis´es sont :

– public Thread() ;

(3)

– public Thread(String) ;

– public Thread(Runnable, String) ; – public Thread(Runnable) ;

– public Thread(ThreadGroup, String) ; – public Thread(ThreadGroup, Runnable) ;

– public Thread(ThreadGroup, Runnable, String) ;

Le param`etre ThreadGroup permet de regrouper un ensemble de thread est de leur donner des propri´et´es communes ou de leur appliquer, `a tous, une mˆeme m´ethode. Une fois l’objet thread cr´e´e au moyen d’un des constructeurs, il faut l’activer (le d´emarrer) par un appel `a la m´ethode start() qui appellera la m´ethodepublic void run()de l’objet contenant le code `a ex´ecuter. Si la m´ethode run() est appel´ee directement, le code de cette m´ethode est ex´ecut´e dans le thread courant.

1 c l a s s monThread e x t e n d s Thre ad

2 {

3 p u b l i c v o i d r u n ( ) {

4 f o r (i n t i = 1 ; i <5 ; i ++)

5 System . o u t . p r i n t l n ( ” j e s u i s l e t h r e a d ”+getName ()+ ” i =”+ i ) ;

6 }

7 }

8

9 p u b l i c c l a s s e x o 1

10 {

11 p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) {

12 Thre ad t h 1 = new monThread ( ) ;

13 Thre ad t h 2 = new monThread ( ) ;

14 t h 1 . s t a r t ( ) ;

15 t h 2 . s t a r t ( ) ;

16 System . o u t . p r i n t l n ( ” J e s u i s l e t h r e a d p r i n c i p a l ” ) ;

17 }

18 }

Listing 1 – Cr´eation de deux threads

1. En vous inspirant du code donn´e, ´ecrire deux programmes pour cr´eer des threads au moyen des deux m´ethodes ´evoqu´ees.

2. Modifier les programmes pour cr´eer 5 threads dans une boucle.

3. Taper le programme 1, l’ex´ecuter et interpr´eter le r´esultat.

4. Pourquoi ce programme ne met pas en ´evidence le fonctionnement multi-tˆache du syst`eme d’exploitation ? Modifier le programme afin de faire apparaˆıtre ”l’effet multi-tˆache”.

5. Quel peut ˆetre l’inconv´enient de la m´ethode de cr´eation et de d´emarrage des threads (surtout dans le cas d’une utilisation de plusieurs threads en boucle) ?

Exercice 2. Thread et priorit´ e

Pour chaque thread cr´ee il est possible de lui associer une priorit´e au moyen de m´ethodes d´efinies dans la classe java.lang.Thread.

Un objet de la classeThreadpermet de contrˆoler un processus l´eger qui peut ˆetre actif, suspendu ou arrˆet´e. Au lancement d’un programme un seul thread s’ex´ecute, c’est le thread initial. On peut le contrˆoler via la m´ethode de classe : public static Thread currentThread() ; Il est ensuite possible de modifier les attributs du thread en le manipulant via les m´ethodes d’instance de l’objet retourn´e.

1 c l a s s e x o 2{

2 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n{

3 Thre ad t h r e a d I n i t i a l = Thre ad . c u r r e n t T h r e a d ( ) ;

(4)

4 // Donner un nom au t h r e a d

5 t h r e a d I n i t i a l . setName ( ”Mon t h r e a d ” ) ;

6 // A f f i c h e r l e nom du t h r e a d

7 System . o u t . p r i n t l n ( t h r e a d I n i t i a l ) ;

8 // F a i r e d o r m i r l e t h r e a d 2 s e c

9 Thre ad . s l e e p ( 2 0 0 0 ) ;

10 System . o u t . p r i n t l n ( ” f i n ” ) ;

11 }

12 }

Il est possible de changer la priorit´e d’un thread afin qu’il ait une priorit´e particuli`ere pour acc´eder au processeur. Par convention, le thread de plus forte priorit´e acc`ede plus souvent au processeur.

Par d´efaut, un thread a la priorit´e de son parent. Pour changer la priorit´e d’un thread la m´ethode public void setPriority (int)est disponible et pour visualiser la priorit´e on utilisepublic int getPriority ().

De plus, il existe des constantes pr´ed´efinies pour les valeurs des priorit´es (membres de la classe Thread) :

– public final static int MAX PRIORITY ; – public final static int MIN PRIORITY ; – public final static int NORM PRIORITY ;

Il n’est pas possible de sortir de ces bornes sous peine de recevoir une exception.

Modifier le programme de l’exercice 1 afin de donner diff´erentes priorit´es aux deux threads. Notez vos observations pour chaque type de priorit´e test´e.

Exercice 3. Illustration

R´ealiser un programme qui simule une course de threads. Chaque thread d´emarre et compte jus- qu’a 1000. Dans la boucle simulant le travail du thread, implanter une attente al´eatoire (Math.random()).

Le premier thread arriv´e a 1000 est d´eclar´e gagnant, n´eanmoins les autres thread continuent la course.

Exercice 4. Concurrence

Reprendre l’exemple du cours sur la banque et les distributeurs de billets, afin de mettre en

´

evidence le probl`eme de concurrence.

1. Cr´eer un programme qui lance deux threads qui vont retirer 1000 fois 10 pour l’un et 1000 fois 50 pour l’autre, sur un compte qui comporte 800 000. Quel doit ˆetre le solde du compte ? Qu’observez vous ? Ce r´esultat est il toujours le mˆeme ?

2. Modifier le programme afin de mettre en ´evidence un probl`eme de concurrence.

3. En utilisant le m´ecanisme de moniteur, modifier votre programme afin qu’`a un instant donn´e, un seul thread puisse acc´eder au contenu du compte. V´erifier que son ´ex´ecution est correcte.

Exercice 5. Un exemple r´ eel

On suppose qu’on dispose d’une machine bi-processeur. On veut cr´eer un programme qui permet de calculer les nombres premier compris entre 1 et 50000. Pour exploiter les deux processeurs on utilise deux threads.

1. R´ealiser une premi`ere verison du programme en attibutant l’exploration des l’intervalles 1 - 25000 `a un thread et 25001 - 50000 `a l’autre thread. Quel est l’inconvient de ce programme ? 2. R´ealiser un deuxi`eme version comportant un index qui indique la progression du calcul. Chaque

thread vient consulter l’index pour connaˆıtre le nombre qu’il doit tester. L’algorithme en pseudo-code est le suivant :

(5)

pour i:=1 jusqu’a 50000

nb=lire la valeur de l’index incr´ementer l’index

tester si nb est premier fin pour

Compl´ement et indications pour la r´ealisation des exercices 3,4,5 La JVM ex´ecute les threads jusqu’`a ce que :

– la m´ethodeexit()soit appel´ee ;

– tous les threads qui n’ont pas ´et´e marqu´es Deamon soient termin´es.

Un thread se termine lorsque la m´ethoderun() se termine ou lors de l’appel `a la m´ethodestop() sur une r´ef´erence au thread. Il est possible de suspendre momentan´ement l’ex´ecution d’un thread au moyen de la m´ethodesuspend() et de reprendre l’ex´ecution au moyen de la m´ethoderesume().

La m´ethode destroy() permet de d´etruire un thread sans aucune possibilit´e de r´eaction et en ne lib´erant aucun moniteur. La m´ethode yield() permet de rendre la main. Toutes les op´erations ne sont possibles que si le thread appelant les m´ethodes a le droit d’acc´eder au thread dont on veut modifier l’´etat. Ceci n’est vrai que si les thread appartiennent au mˆeme ThreadGroup.

Chaque thread s’ex´ecutant dans le mˆeme espace d’adressage, il est n´ecessaire d’avoir un m´ecanisme d’exclusion mutuelle entre threads lors des acc`es `a la m´emoire. Java implante le m´ecanisme de moni- teur qui assure que quand une thread rentre dans une portion de code g´er´ee par un moniteur aucune autre thread ne peut y p´en´etrer.

Java garantit atomicit´e de l’acc`es et de l’affectation des types primitifs, sauf les long et les double.

Ainsi deux threads qui modifient de fa¸con concurrente une variable de type double peuvent entraˆıner des r´esultats incoh´erents. De mˆeme pour des objets.

Pour ´eviter ces probl`emes d’incoh´erences Java propose un m´ecanisme d’exclusion mutuelle entre deux threads. Pour cela Java propose le mot clef synchronized qui s’applique `a une portion de code relativement `a un objet particulier. Pendant l’ex´ecution d’un portion de code synchronis´ee par une thread A , toute autre thread essayant d’ex´ecuter une portion de code synchronis´ee sur le mˆeme objet est suspendue. Une fois que l’ex´ecution de la portion de code synchronis´ee est termin´ee par la thread A , une thread en attente et une seule est activ´ee pour ex´ecuter sa portion de code synchronis´ee. Ce m´ecanisme est un m´ecanisme de moniteur. Il peut y avoir un moniteur associ´e `a chaque objet.

Deux constructions sont disponibles :

– synchronized est utilis´e comme modifieur d’une m´ethode. Le moniteur est alors associ´e `a l’objet courant et s’applique au code de la m´ethode ;

– la construction synchronized(o){...}. Le moniteur est associ´e `a l’objet o et s’applique au bloc associ´e `a la construction.

Références

Documents relatifs

D` es que le transfert des donn´ ees est termin´ e, le contrˆ oleur de p´ eriph´ erique informe l’unit´ e centrale qu’il a termin´ e son op´ eration.. Il effectue

Simulez le fonctionnement en utilisant la premi` ere colonne de l’annexe 1. Notez a) le nombre de d´ efauts de pages (chargement d’une page de la m´ emoire virtuelle vers la m´

– au probl` eme de l’exclusion mutuelle pour l’acc` es ` a des donn´ ees (objets) ou ` a du code (m´ ethodes) ; – au probl` eme de la synchronisation sur des ´ ev´

Vous devrez ˆetre capable de donnez des indications de comportement de votre programme (temps, limites m´emoire etc.) dans le cas du stockage d’un grand nombre d’objets de petite

Si vous souhaitez r´ealiser d’autres extensions du langage Redcode, votre interpr´eteur devra ˆetre capable de supporter deux syntaxes : celle des programmes en RedCode

Un utilisateur lance le pro- gramme client, sp´ecifie un r´epertoire du syst`eme de fichiers du client, ceci a pour effet d’initialiser un d´ep ˆot (l’utilisateur peut

Le stockage des mots cl´es, des autorisations sur les images et leur localisation en fonc- tion du nom sont r´ealis´es en utilisant plusieurs DHT (Distributed Hash Table). Vous

Vous devrez ´egalement pr´esenter dans le document l’architecture de votre application, c’est-`a-dire, dans le cadre du module I4b, une conception en couches fonc- tionnelles