Sie sind auf Seite 1von 15

Sylvain RAGOT LSI2 - 25 juin 2010 Wiem EL BARRAH

Langage Java
Mot clefs Naimi - Trehel
RMI - Thread

Algorithmique Distribuée
I Encadré par : Damien LOLIVEJ

Jeu de domino en réseau

Résumé : Ce document rend compte des traveaux réalisés dans le cadre des 8h de projet
consacrées à la réalisation d’un jeu de domino en réseau. L’architecture aura pour support l’al-
gorithme de Naimi et Tréhel pour la gestion de l’exclusion mutuelle et les échanges entre les
objets seront gérés par RMI (Remote Method Invocation).

— ENSSAT - Université de Rennes 1 —


École Nationale Supérieure de Sciences Appliquées et de Technologie
6, rue de Kerampont - 22305 LANNION - FRANCE
Téléphone : 02 96 46 91 48 - Télécopie : 02 96 46 66 75
http ://www.enssat.fr/
Table des matières

Introduction 2

I Analyse & Conception 3


I.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
I.2 Choix d’implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
I.2.a) Le parallélisme - Les threads . . . . . . . . . . . . . . . . . . . . . . . . . 4
I.2.b) La communication - RMI . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
I.3 Présentation de l’algorithme de Naimi et Tréhel . . . . . . . . . . . . . . . . . . . 5
I.3.a) Communication arbitre-Parti applicative . . . . . . . . . . . . . . . . . . . 6
I.3.b) Communication applicative-Controle . . . . . . . . . . . . . . . . . . . . . 6
I.3.c) Communication Contrôle joueur « i »-contrôle joueur « j » . . . . . . . . 6
I.4 Diagramme de classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
I.4.a) Première version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
I.4.b) Seconde version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

II Réalisation & Exploitation 10


II.1 Implémentation de RMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
II.1.a) Détail de l’implémentation . . . . . . . . . . . . . . . . . . . . . . . . . . 10
II.1.b) Le plug-in Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
II.2 Du CSP au Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
II.2.a) L’arbitre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
II.2.b) La partie applicative du joueur . . . . . . . . . . . . . . . . . . . . . . . . 12
II.2.c) La partie contrôle du joueur . . . . . . . . . . . . . . . . . . . . . . . . . . 12
II.3 Jeu d’essai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
II.4 Comparaison avec l’algorithme de Lamport . . . . . . . . . . . . . . . . . . . . . 13

Conclusion 14

1
Introduction

Le but de ce projet est d’implémenter et tester l’algorithme de Naimi et Tréhel. Cette


implémentation à pour support un jeu de domino en réseau où les différents joueurs peuvent
être répartis sur des sites distants. L’algorithme de Naimi et Tréhel permet de gérer l’exclusion
mutuelle des sites qui veulent, dans le cas présent, pouvoir accéder à la partie.

Cette réalisation est donc centrée autour des entités suivantes :


– une table de jeu qui représentera notre section critique puisqu’au plus un site peut y
accéder à un instant donné ;
– un site arbitre qui coordonne le début et la fin de la partie ;
– plusieurs sites joueurs qui placent des dominos sur la table de jeu.

Puisqu’il est évident que ces objets distants doivent communiquer, un mécanisme de par-
tage doit être mis en place pour assurer cette communication. En effet, RMI permet l’accès aux
méthodes dobjets distants, permettant ainsi d’établir une communication riche.

Nous présenterons dans ce document l’analyse et la conception de notre solution avant de


parler de la réalisation et de faire un point sur l’avancement du projet.

Commentaires :

Note : certains passages de ce document ont purement vocation d’aide mémoire personnels pour d’éventuelles
réutilisations des concepts vus ici.

2
I Analyse & Conception

I.1 Présentation
Nous présentons ici la problématique posée par la l’exclusion mutuelle (locale et distribuée)
qui sous-tend l’existence de cet algorithme. Nous allons donc rappeler très brièvement le principe
de ces notions qui sont indispensables à la compréhension du sujet et à sa réalisation :

Exclusion mutuelle

– Contexte de plusieurs processus s’exécutant en parallèle


– Accès à une ressource partagée par un seul processus à la fois
Exclusion mutuelle distribuée

– Accès à une ressource partagée distante par un seul processus à la fois


– L’une des meilleures méthodes (du point de vue de l’utilisation du réseau) de contrôle
est le contrôle par jeton
• un jeton circule entre les processus et donne l’accès à la ressource
• la gestion et l’affectation du jeton — et donc l’accès à la ressource — est faite par
les processus entre eux
• Deux approches : jeton circulant en permanence ou affecté à la demande des
processus
– Processus distribués
• Requêtes et gestion d’accès via des messages échangés entre les processus
• Nécessité de mettre en œuvre des algorithmes gérant ces échanges de messages
pour assurer l’exclusion mutuelle
Comme il l’est indiqué, nous devons réaliser une application permettant de jouer en réseau
aux dominos. Un arbitre et un ensemble des joueurs sont les acteurs de ce jeu. En fait, l’arbitre
supervise les parties. Lorsqu’un joueur veut participer à une partie, il doit envoyer une demande
d’inscription auprès de l’arbitre. C’est ensuite l’arbitre qui distribue les dominos d’une façon
aléatoire aux différents joueurs et décide lequel parmi eux débute la partie. Une partie ne peut
démarrer, c’est-à-dire l’arbitre ne donne pas l’ordre de commencement, tant qu’il n y a pas un
nombre suffisant de joueurs. Ensuite, chaque joueur demande à jouer de façon aléatoire et ne
peut effectivement jouer que lorsqu’il est en possession du jeton. L’ordre de passage des joueurs
est ainsi aléatoire et rien ne peut garantir que tous les joueurs joueront le même nombre de
coups durant la partie.

Le joueur possédant le jeton doit poser l’un de ses dominos sur la table de jeu. S’il ne peut
pas, il prend alors un domino de la pioche qu’il pose ou qu’il garde. Ce dernier passe ensuite le
jeton au joueur ayant demandé à jouer après lui c’est dire le joueur qui se trouve en tête de la
file d’attente d’accès à la section critique 1 .

1
Voir Structures de données I.4.a) page 7

3
I.2. CHOIX D’IMPLÉMENTATION I. Analyse & Conception

Lorsqu’un joueur ne dispose plus de dominos, il le signale à l’arbitre qui envoi à ce joueur le
message “fin de partie” et informe les autres joueurs qu’il y a un gagnant.

Nous nous intéressons dans ce projet à l’implémentation ce jeu à l’aide de L’algorithme pro-
posé par Naı̈mi et Tréhel pour la gestion de la partie accédée en exclusion mutuelle distribuéee.
Cet algorithme assure le bon déroulement des parties conformément à ce qui a été cité dans la
section précédente. Il appartient à la famille basée sur la notion de jeton unique.

I.2 Choix d’implémentation


I.2.a) Le parallélisme - Les threads
Le fait que les différents joueurs soient répartis et que chacun puisse faire des demandes à
tout moment veut dire qu’ils doivent être gérés en parallèle. Pour réaliser cela, la solution la
plus courante car pratique et légère est d’utiliser un tread pour chaque site. Leur mise en œuvre
est assez aisée et se déroule comme suit :
– la classe dont les objets seront instanciés dans des threads différents hérite de la classe
Thread (public class ... extends Thread{...}). Cette classe propose l’unique méthode run()
qui décrit les actions réalisées par l’exécution de thread.
ou
– si la classe dont les objets seront instanciés dans des threads différents hérite déjà d’une
classe, la mise en œuvre des thread passe par l’implémentation de l’interface Runnable 2 .
La création et l’exécution du thread se fait par l’appel à la méthode objet.start(). Notons
également que toutes les classes filles héritent, par construction, de la classe Thread (ou doivent
implémenter Runnable suivant le schéma suivi par leur classe.

Dans notre cas, l’arbitre et les joueurs sont tous dans des threads séparés puisqu’ils héritent
de Site qui elle-même hérite de Thread. Le comportement général d’un arbitre ou d’un joueur,
quel qu’il soit passe donc par la redéfinition de la méthode run().

I.2.b) La communication - RMI


I.2.b.i) Présentation
Une fois configuré, RMI 3 , par l’accès à des méthodes d’un objet
distant permet la communication entre ces objets en faisant transiter
toutes sortes de données, que ce soit des chaı̂nes de caractère ou des
objets plus complexes. Ainsi, à titre exemple, l’arbitre pourra com-
muniquer des objets dominos.
La configuration nécessaire au bon fonctionnement se fait en 5
étapes :
1. Spécifier l’interface de l’objet ;
2. Implanter l’interface du côté serveur ;
3. Générer le talon et le squelette de l’objet distant ;
4. Définir l’objet (l’exposer) afin de le rendre visible aux clients ;
5. Réaliser les appels distants au travers d’applications clientes ;
Notons, que comme pour les threads, cette étape peut se faire en
héritant de la classe UnicastRemoteObject, ou pas, si un héritage est
déjà présent.
Ces étapes seront développées dans le chapitre suivant du point de vue de l’implémentation.
2
pas d’héritage multiple en Java
3
Remote Method Invocation

4
I.3. PRÉSENTATION DE L’ALGORITHME DE NAIMI ET I.
TR Analyse
ÉHEL & Conception

Une autre solution aurait été d’utiliser les sockets comme vecteur d’acheminement des mes-
sages. Initialement, mon choix s’est porté sur RMI pour les raisons suivantes :
– très pratique, une fois configuré ;
– semble plus flexible que les sockets quand à la nature des messages ;
– (l’occasion de le découvrir.)
Sur le second point, il semble toutefois que l’on puisse véhiculer tout type de données, y
compris des objets. À la suite des séances de TP, nous n’avions vu que des échanges de chaı̂nes
de caractères, car facile à réaliser. Cependant, en sérialisant un objet, il serait possible de le
transformer en flot de bit qui est le véritable contenu des messages transitant via les sockets.
De plus, au regard des difficultés rencontrées pour la configuration de RMI, une solution plus
“efficace” par sockets aurait certainement été plus bénéfique puisque la mise en place de RMI
n’est qu’un outil et non l’objet du projet.

I.2.b.ii) Définition des interfaces


Nous nous intéressons ici à la spécification des interfaces définissant les méthodes accessibles
à l’objet distant. Elles sont constituées de la suite des prototypes des méthodes concernées.
Principe : Soit l’échange suivant :
début de la partie
joueur (applicatif) arbitre
fin de la partie

Cela se traduit par :


→ une méthode debutPartie(...) dans la classe JoueurPartieApplicative, ainsi que dans
l’interface correspondante, méthode qui sera appelée depuis l’aribtre.
→ une méthode finPartie(...) dans la classe Arbitre, ainsi que dans l’interface corres-
pondante, méthode qui sera appelée depuis la partie applicative du joueur.

• Interface du joueur :
• Interface de l’arbitre :
// Vers l’arbitre
// Vers la partie applicative des joueurs
→ debutPartie(int num joueur)
→ finPartie(int num joueur)
// Vers la partie contrôle (des autres joueurs)
→ enviePartie(int num joueur)
→ demandeSC(int num joueur)
→ donneJeton(int num joueur)

I.3 Présentation de l’algorithme de Naimi et Tréhel


L’algorithme assure une évolution dynamique du système. En effet le graphe de communica-
tion peut se transformer et prendre plusieurs formes au cours de l’exécution de l’algorithme. Le
changement du graphe s’effectue grâce aux envois des requêtes (et non lors de l’envoi de jeton).
Quand un site décide d’entrer en section critique il envoie une requête à un seul site prédéfini
(appelé dernier ou père).
On constate donc la présence de messages de deux types circulant entre les sites :
– message de requête
– message de transmition du jeton

La structure arborescente permet de faire transiter la demande jusqu’à la racine. Les de-
mandeurs de la section critique sont mis en attente dans une file globale. Chaque demande
d’entrée en section critique doit être transmise au site successeur et chaque demandeur devient
la nouvelle racine. La mise à jour de l’arborescence est bien illustrée par un exemple dans le sujet.

5
I.3. PRÉSENTATION DE L’ALGORITHME DE NAIMI ET I.
TR Analyse
ÉHEL & Conception

La figure suivante (fournie) montre la structure utilisée pour notre application :

Fig. I.1 – Synoptique des communications inter-sites

D’après le schéma, nous pouvons constater qu’un site joueur est décomposé en deux parties.
Une partie applicative qui communique avec l’arbitre qui lui aussi doit pouvoir communiquer
avec tous les joueurs. Une partie contrôle qui assure la communication avec les autres joueurs
et l’exclusion mutuelle.

I.3.a) Communication arbitre-Parti applicative


Un joueur commence par faire une inscription en envoyant le message Envie-partie-dominos
et déclare la fin de sa partie en envoyant le message fin-partie.
À son tour, un arbitre envoie un message debut-partie si les conditions sont vérifiées pour
lancer une partie de domino.

I.3.b) Communication applicative-Controle


Le message Envie jouer coup exprime que la partie applicative du joueur veut entrer en
section critique. Il faut ensuite tester si le joueur est en possession du jeton ou pas. Si oui, la
partie contrôle lui envoie le message OK coup en lui autorisant l’accès à la section critique. Quand
le joueur finit son tour, il sort de la section critique en envoyant le message fin-coup à sa partie
applicative.

I.3.c) Communication Contrôle joueur « i »-contrôle joueur « j »


Le message jeton est envoyé au site suivant dans la file d’attente. Si le site de contrôle ne
possède pas le jeton et sa partie applicative désire entrer en section critique, il envoie le message
avec contraire Dem-SC contenant son identifiant à son site père et se met en attente. Le transit
d’un tel message dans l’arborescence nécessite la mise à jour de l’arborescence.
Cette figure fait également apparaı̂tre les divers services que doivent offrir les différents sites.

6
I.4. DIAGRAMME DE CLASSES I. Analyse & Conception

Une fois ce schéma réalisé, il ne nous reste plus qu’à définir les méthodes qui n’y apparaissent
pas et qui sont pourtant indispensable. Nous pouvons ensuite programmer les différents processus
indépendamment les uns des autres car les communications entre eux sont maintenant définies.

I.4 Diagramme de classes


I.4.a) Première version

Fig. I.2 – Diagramme de classe — 1ere version

Grâce à ce schéma, on peut mettre en avant plusieurs points :


Les structures de données : l’algorithme de Naimi et Tréhel dont nous venons de parler
maintient deux structures de données : un arbre modifié au fur et à mesure des entrées /

7
I.4. DIAGRAMME DE CLASSES I. Analyse & Conception

sorties en section critique des différents sites. La racine de cet arbre, appelée dernier, est
le dernier site émetteur d’une requête d’entrée en section critique. La seconde structure
représente la file d’attente pour l’accès à cette section critique.
Ces structures sont éclatées et réparties sur chacun des sites. Ainsi, en négligeant les
messages en cours de transmition entre les sites, on peut représenter l’état du système de
la manière suivante : (ici, l’initialisation)
/-----+------+------+------+------\
| P1 | P2 | P3 | P4 | P5 |
----------|------+------+------+------+------|
dernier | nil | P1 | P1 | P1 | P1 | <= arbre des demandes de s.c.
suivant | nil | nil | nil | nil | nil | <= file d’attente de s.c.
jeton | vrai | faux | faux | faux | faux |
demandeur | vrai | faux | faux | faux | faux |
---------/ \-----+------+------+------+------/
qui décrit donc un état dans lequel P1 est le seul site à avoir fait une demande et pour
lequel la file d’attente est vide.
La classe Application : Il s’agit ici d’un raccourcis permettant de créer les objets arbitre et
joueur. Dans la pratique, la création de ces objets doit leur être propre - on doit avoir la
possibilité de créer un joueur à n’importe quel instant.
La classe Joueur : Un joueur sera composé d’une partie applicative et d’une partie contrôle.
L’application a en charge le dialogue avec l’arbitre signalant, par exemple, son arrivée ou la
de la partie. Alors que le contrôle permet la communication entre les joueurs et notamment
les échanges du jeton ou la demande d’entrée / sortie de section critique.
En “langage RMI”, cela veut dire que :
– l’arbitre possède un talon pour chacun des (partie applicative des) joueurs ;
– la partie applicative d’un joueur à connaissance du talon de l’arbitre ;
– la partie contrôle connaı̂t les talons des autres parties contrôles.
La classe Table : existe dans la modélisation mais n’est pas réalisée.
Factoriser du code : Cette décomposition hiérarchique est sensée permettre de factoriser, à
différents étage, du code qui serait inutilement répété. En plus des accesseurs, comme
chaque site est à la fois client et serveur dans la communication, on pourrait également
envisager d’y placer les instructions réalisant cette communication bidirectionnelle.
Cependant, cette modélisation considère un arbitre comme étant un Site à part entière. Hors,
il n’intervient nullement dans la gestion de l’exclusion mutuelle. Nous avons donc retouché notre
modélisation pour en arriver au diagramme de classe présente à la figure I.3 page 9.

I.4.b) Seconde version


Cette version a les mêmes caractéristique que la précédente : les structures de données
sont toujours réparties, le joueur conserve ses parties applicative et contrôle, mais l’arbitre est
maintenant une entité distincte.
On pourra également remarquer la présence des classes suivantes (existentes également dans
la première version) :
La classe Domino : constituée de 2 attributs (partieGauche et partieDroite), elle modélise un
domino.
La classe Pioche : est initialement constituée de l’ensemble des dominos (Domino) existants
puis, au fur et à mesure de la partie, les dominos vont de la pioche vers les joueurs.

8
I.4. DIAGRAMME DE CLASSES I. Analyse & Conception

Fig. I.3 – Diagramme de classe — 2nde version

9
II Réalisation & Exploitation

II.1 Implémentation de RMI


II.1.a) Détail de l’implémentation
Le détail de l’implémentation de RMI reprend les différentes étapes vues en page 4.
0. le registre RMI : il contient la liste des objets partagés ainsi que les méthodes disponibles.
C’est un composant essentiel au fonctionnement de l’échange. Il est possible de le lancer
soit en ligne de commande (Unix) avec rmiregistry& (en tâche de fond), soit directement
dans le code. Cette dernière solution permet d’avoir un code plus portable est surtout plus
simple pour l’utilisateur. Pour ce faire, il convient d’insérer à l’endroit désiré :
try { 1
j a v a . rmi . r e g i s t r y . L o c a t e R e g i s t r y . c r e a t e R e g i s t r y ( 1 0 9 9 ) ; /∗ p o r t par d e f a u t ∗/ 2
System . out . p r i n t l n ( ”Le RMI r e g i s t r y e s t p r e t . ” ) ; 3
} catch ( Exception e ) { 4
System . e r r . p r i n t l n ( ”Le RMI r e g i s t r y n ’ a pas demmare c o r r e c t e m e n t . ” ) ; 5
} 6

1. Spécifier l’interface de l’objet qui est un fichier .java avec la structure suivante :
import j a v a . rmi . RemoteException ; 1
2
p u b l i c i n t e r f a c e I n t e r f a c e A r b i t r e e x t e n d s j a v a . rmi . Remote { 3
/∗ p r o t o t y p e d e s methodes p a r t a g e e s ∗/ 4
p u b l i c v o i d f i n P a r t i e ( i n t num joueur ) throws RemoteException ; 5
} 6

2. Implanter l’interface du côté serveur : implémenter l’interface


public c l a s s Arbitre extends . . . 1
implements . . . , S e r i a l i z a b l e , I n t e r f a c e A r b i t r e { 2
. . . /∗ methodes p a r t a g e e s ou non ∗/ 3
p u b l i c v o i d f i n P a r t i e ( i n t num joueur ) { . . . } 4
... 5
} 6

3. Générer le talon et le squelette de l’objet distant : rmic. La génération des talons fait en
ligne de commande une fois que l’interface est définie et implémentatée.
cd <c h e m i n P r o j e t >/b i n / 1
rmic <nomPackage>.<nomClasse> 2

La classe en question est celle qui implémente l’interface et son nom est donnée sans le
.class. Cela a pour effet de générer des fichiers <nomClasse> Stub.class.
4. Définir l’objet (l’exposer) afin de le rendre visible aux clients : le rebind
S t r i n g machine = l o c a l h o s t ; 1
String port = 1099; 2
S t r i n g objetToRebind = a r b i t r e 3

10
II.2. DU CSP AU JAVA II. Réalisation & Exploitation

i f ( System . g e t S e c u r i t y M a n a g e r ( ) == n u l l ) { System . s e t S e c u r i t y M a n a g e r ( new 4


SecurityManager ( ) ) ;
try { 5
Naming . r e b i n d ( ” // ”+machine+” : ”+p o r t+” / ”+objetToRebind , t h i s ) ; 6
System . out . p r i n t l n ( ”>> A r b i t r e > Lancement du S e r v e u r RMI ” ) ; 7
} c a t c h ( RemoteException e ) { 8
e . printStackTrace () ; 9
} c a t c h ( MalformedURLException e ) { 10
e . printStackTrace () ; } 11

5. Réaliser les appels distants au travers d’applications clientes : le lookup


S t r i n g machine = l o c a l h o s t ; 1
String port = 1099; 2
S t r i n g objetToLookup = a r b i t r e 3
( I n t e r f a c e A r b i t r e ) t a l o n A r b i t r e = ( I n t e r f a c e A r b i t r e ) Naming . loo kup 4
( ” rmi : / / ”+machine+” : ”+p o r t+” / ”+objetToLookup ) ;

II.1.b) Le plug-in Eclipse


Eclipse dispose de plug-in pratiques pour la gestion des applications utilisant RMI. On peut
citer par exemple genady qui propose notament un inspecteur du registre RMI 1 2 .

II.2 Du CSP au Java


II.2.a) L’arbitre
Comme nous l’avons dit, l’arbitre communique avec la partie applicative de tous les joueurs
participants au jeu. L’arbitre a pour rôle alors de lancer une partie, distribuer les dominos d’une
façon aléatoire et signaler la fin de la partie à tous les joueurs et leur communiquer le vainqueur.
Nous avons commencé par déterminer le fonctionnement de l’arbitre en langage CSP. Comme
le montre le code suivant :

Processus Arbitre ::
variable nbDemandeur entier,
variable list_joueur_inscrit tableau de booleen,
variable start booleen,
variable j entier

*[ Joueur[i] ? (Envie-partie-dominos) ->


nbDemandeur = nbDemandeur+1 ;
list_joueur_inscrit[i]=true ;
[]! start ;nb_demandeur_inscrit =2 -> start := true ; j :=0 ;
*[ j<taille_list _joueur_inscrit;
list_joueur_inscrit[j] -> joueur[j] ! (Début-partie) ;
j=j+1 ;
]
[] Joueur[i]?(Fin-partie) -> start :=false ; j := 0 ;
*[ j<taille_list _joueur_inscrit ;
list_joueur_inscrit[j] -> joueur[j] !(Fin_partie(gagnant)) ;
j=j+1 ;
];
]
1
présentaiton : http://www.genady.net/rmi/v20/ (EN)
2
installation : http://www.genady.net/rmi/v20/docs/installation/update_install.html (EN)

11
II.2. DU CSP AU JAVA II. Réalisation & Exploitation

Une fois la spécification CSP faite, nous pouvons le coder en Java. L’arbitre est unique dans
une partie et contient les variables suivantes :
private Pioche p i o c h e ; /∗ i n s t a n c e de l a c l a s s e P i o c h e ∗/ 1
private boolean s t a r t ; /∗ b o o l e e n q u i i n d i q u e s i une p a r t i e e s t commencee ∗/ 2
private b o o l e a n [ ] l i s t j o u e u i n s c r i t ; /∗ d e f i n i t l a l i s t e d e s j o u e u r s i n s c r i t s ∗/ 3
private i n t nbDemandeur ; /∗ nombre de j o u e u r q u i ont f a i t une demande de j e u ∗/ 4

Cette classe possède d’autres méthodes pour assurer la distribution des dominos, avec entre
autres :
→ public void genererDominos() qui génère les 28 dominos pour jouer et les place dans la pioche.
→ public LinkedList<List<Domino>> distribuerDomino (int nbJoueur) qui permet de créer à partir
des dominos présents dans la pioche des listes de 7 dominos, attribués à chaque joueur.
→ La méthode public synchronized void Envie partie( int num joueur)throws RemoteException est rap-
pelée par la partie applicative d’un joueur quand ce dernier veut jouer une partie. Cela
incrémente le nombre de joueurs qui ont demandé de jouer. Nous testons par la suite
si ce nombre est égal au nombre minimal de joueurs qui est fixé à 2 dans notre projet.
Dans ce cas, l’arbitre signale aux joueurs inscrits le début de la partie et leurs distribue
les dominos.
→ Si un joueur n’a plus de dominos, il rappelle la méthode public void finPartie ( int idJoueur)
throws RemoteException pour signaler la fin de la partie. L’arbitre envoi aux autres joueurs
l’identité du joueur vainqueur qui est le joueur qui a évoqué la méthode.

II.2.b) La partie applicative du joueur


La méthode public void debutPartie(LinkedList<Domino> listDom) de passer au joueur une liste
de dominos qu’il utilisera pour jouer. Elle est appelée par arbitre lorsqu’il signale au joueur le
début de partie.
Nous utiliserons aussi des méthodes pour fournir à l’arbitre les informations nécessaires sur
le jeu. Ces informations sont utilisées quand l’arbitre veut diffuser la fin de la partie de joueur.
Nous aurons besoin aussi d’une méthode qui permet à l’arbitre de donner le jeton à l’un des
joueurs.
Pour la communication avec la partie contrôle, nous utiliserons la méthode ok Coup() qui
permet au contrôleur de signaler à la partie applicative que le joueur a le jeton et peut alors
entrer en section critique pour jouer.

II.2.c) La partie contrôle du joueur


L’algorithme de Naimi et Tréhel sera géré et appliqué dans cette classe. Elle correspond
au processus de contrôle d’un joueur et c’est à travers de ce processus que les propriétés de
l’algorithme seront conservées, notamment l’exclusion mutuelle des différents joueurs sur la
table de jeu.
L’implémentation de ce la partie contrôle du joueur consiste à traduire en Java le code CSP
qui nous est fourni.
Pour assurer la communication avec la partie applicative et la partie contrôle des autres
joueurs, nous définissons une interface InterfacePartieControle qui regroupe les prototypes des
méthodes suivantes :
– envieJouerCoup() : invoquée par la partie applicative du joueur lorsque l’utilisateur sou-
haite entrer en section critique ;
– finCoup() : : invoquée par la partie applicative afin de signaler que l’utilisateur a terminé
le coup qu’il était en train de jouer et qu’il libère la section critique ;
– demSC(int num joueur) : invoquée par la partie contrôle du joueur i. Elle permet de
signaler au contrôleur que le site i fait une demande section critique ;

12
II.3. JEU D’ESSAI II. Réalisation & Exploitation

– jeton() : invoquée par un autre contrôleur afin de passer le jeton au site.

II.3 Jeu d’essai


Le RMI registry est pret.
je m’appelle Thread-3 et j’aimerais commencer une partie
nombre de demandeurs : 1 (joueur 1)
Erreur Arbitre: envoie debut de jeu au joueur 2: joueur2
je m’appelle Thread-7 et j’aimerais commencer une partie
Erreur Arbitre: envoie debut de jeu au joueur 3: joueur3
nombre de demandeurs : 1 (joueur 2)
Erreur Arbitre: envoie debut de jeu au joueur 4: joueur4
je m’appelle Thread-12 et j’aimerais commencer une partie
nombre de demandeurs : 1 (joueur 3)
je m’appelle Thread-18 et j’aimerais commencer une partie
nombre de demandeurs : 1 (joueur 4)
Que la partie commence!!!
listDominos du joueur 1 : [ 5|1 , 2|0 , 5|2 , 2|1 , 6|4 , 4|4 , 5|3 ]
listDominos du joueur 2 : [ 3|0 , 3|1 , 4|1 , 6|3 , 6|5 , 1|0 , 0|0 ]
listDominos du joueur 3 : [ 5|0 , 6|6 , 6|1 , 4|2 , 4|3 , 3|2 , 3|3 ]
listDominos du joueur 4 : [ 5|5 , 2|2 , 6|0 , 1|1 , 6|2 , 5|4 , 4|0 ]
Les joueurs et l’arbitre sont lances

Malgré sa concision, l’exemple précédent montre plusieurs aspects :


– les joueurs et l’abitre sont correctement créés dans leur thread respectif ;
– ils se connectent à l’arbitre et font leur demande pour pouvoir jouer ;
– en retour, il recoivent une liste de domino aléatoires, tirés de la pioche. Cet échange valide
le fonctionnement de RMI.

II.4 Comparaison avec l’algorithme de Lamport


Dans l’algorithme de Lamport, un processus demandeur doit envoyer (N-1) messages requête
aux autres processus. Par la suite, il attend (N-1) messages réponse pour accéder à la section
critique ; enfin à sa sortie de la section critique, il doit envoyer (N-1) messages libération. Par
conséquent, tout accès à la section critique nécessite 3 × (N − 1) messages.
Quant à l’algorithme de M. Tréhel et M. Naı̈mi, son principe se base sur la construction
d’une chaine de «Suivant» ce choix permet de minimiser le nombre des messages, l’envoi est
seulement destiné à suivant. Il conserve ainsi la complexité originale en O(log(n)), limite l’utili-
sation de la diffusion sur le réseau et minimise le nombre des ré-émissions de requêtes en cas de
défaillances. Une étude de performance, réalisées dans un cadre réel, a permis de montrer qu’il
est particulièrement bien adapté aux systèmes répartis à grande échelle.

13
Conclusion

État d’avancement
À l’issue de ce projet, le produit rendu est assez loin de l’objectif de ce projet qui était
d’implémenter et de tester un algorithme de gestion de l’exclusion mutuelle. Cependant, les
réflexions que nous avons pu avoir sur les codes CSP, celui de la partie contrôle qui était fournit
ou de la partie applicative que nous avons développée ont tout de même fait naı̂tre quelques
interrogations.
Comme le montrait le dernier exemple, la communication entre les sites et le début de la
partie fonctionne (moyennant encore quelques petites erreurs). Nous nous sommes d’ailleurs
concentré en priorité sur l’arbitre et la partie applicative du joueur, le contrôle et la gestion de
l’exclusion mutuelle étant correctement détaillé dans le sujet.

Apports & Problèmes rencontrés


Les principaux problèmes que nous avons rencontrés sont plus axés sur la communication
que sur l’aspect distribué du projet, que, de fait, nous n’avons pas encore approndi. Que ce soit
d’ailleurs la communication entre les objets par l’implémentation de RMI que la communication
entre nous !
Par conséquent, les apports de ce projet en terme d’algorithmique distribuée sont limités,
exception faite de la mise en place de l’outil de communication qu’est RMI.
En revanche, nous avons pu nous rendre compte, si besoin était, de la nécessité d’une bonne
spécification !

14

Das könnte Ihnen auch gefallen