• Aucun résultat trouvé

Deux exemples de protocoles non-tol´erants aux fautes

Dans le mod`ele `a passage de messages, le protocole basique de parcours en profondeur ([Cha82]) fonctionne comme suit. Au d´ebut d’un parcours en profondeur, l’initiateur cr´ee un jeton et marque les canaux de tous ses voisins comme “non visit´e”. Puis, il choisit un voisin comme successeur courant dans le parcours, lui envoie le jeton et marque son canal comme “visit´e”.

Lorsqu’un processeur — y compris l’initiateur — rec¸oit le jeton, celui-ci marque le canal de l’´emetteur comme “visit´e”. Ensuite, s’il s’agit de la premi`ere r´eception du jeton alors le processeur rep`ere l’´emetteur du jeton comme son p`ere dans le parcours et marque les canaux de tous ses voisins sauf celui de son p`ere comme “non visit´e”. Puis, dans tous les cas, le processeur ex´ecute les actions suivantes :

– Soit tous les canaux du processeur sont marqu´es “visit´e” et, dans ce cas, si le processeur est l’initiateur du parcours alors il d´ecide (et le parcours est termin´e) sinon il renvoie le jeton `a son p`ere.

– Soit le processeur a des canaux qui sont marqu´es “non visit´e”. Dans ce cas, si le processeur n’a pas de successeur courant (c’est la premi`ere fois qu’il rec¸oit le jeton) ou si l’´emetteur du jeton est son successeur courant alors il choisit un (nouveau) successeur courant parmi ses voisins dont le canal est marqu´e “non visit´e”, lui envoie le jeton et marque son canal comme “visit´e”. Dans le cas contraire, le processeur renvoie le jeton `a l’´emetteur.

La figure 5.1.1 nous montre un parcours en profondeur `a partir du processeur r pouvant ˆetre ex´ecut´e avec le protocole pr´ec´edent. Dans cette figure, les v-arˆetes sont repr´esent´ees par les lignes pleines et nous pouvons remarquer qu’elles d´efinisssent un arbre couvrant en profondeur enracin´e en r. Au contraire, le parcours pr´esent´e dans la figure 5.3.2 n’est pas un parcours en profondeur. En effet, il n’y a, par exemple, pas de relation ancˆetre/descendant entre les deux voisins 1 et 3, donc, l’arbre d´efini par les v-arˆetes ne v´erifie pas la d´efinition A.2.12 (page 161) : ce n’est pas un arbre couvrant en profondeur.

Dans cette th`ese, nous nous sommes int´eress´es au parcours en profondeur dans un r´eseau enracin´e quelconque o`u la racine, r, correspond toujours `a l’initiateur du parcours. Ensuite, nos protocoles uti-lisent une m´ethode classique des syst`emes distribu´es pour parcourir le r´eseau en profondeur d’abord. Cette m´ethode est pr´esent´ee dans la remarque suivante :

Remarque 5.3.1 Classiquement, dans le mod`ele `a ´etats, un parcours en profondeur est ex´ecut´e en utilisant un jeton. `A partir de la racine (r), le jeton est pass ´e de voisin en voisin via des processeurs non visit´es jusqu’`a ce qu’il atteigne un processeur ayant tous ses voisins visit ´es. `A partir de l `a, le

5.3 Deux exemples de protocoles non-tol´erants aux fautes. 45

jeton remonte dans l’arbre couvrant en construction via les liens p `eres jusqu’`a ce qu’il atteigne un processeur p v´erifiant l’un de ses deux cas :

– p a des voisins non visit´e. Dans ce cas, le jeton est pass´e `a un voisin non visit´e de p et le parcours reprend comme pr´ec´edemment.

– p = r et tous les voisins de p sont visit ´es. Dans ce cas, r d´ecide de la terminaison du parcours.

Suivant la m´ethode pr´esent´ee dans la remarque 5.3.1, nous pr´esentons maintenant un protocole de parcours en profondeur simple conc¸u pour un environnement sans faute et ´ecrit dans le mod`ele `a ´etats. Ce protocole, appel´eDFS0, fonctionne dans des r´eseaux enracin´es de topologie quelconque.

Il est present´e dans les algorithmes 5.3.1 et 5.3.2. Le protocoleDFS0 est divis´e en deux phases :

– La phase de visite o`u un jeton visite les processeurs en profondeur d’abord (cette phase est aussi appel´ee circulation de jeton).

– La phase de nettoyage o`u les traces du parcours sont effac´ees pour permettre `a la racine d’initier une autre circulation de jeton.

Pour r´ealiser ces deux phases, chaque processeur p du protocole maintient les deux variables sui-vantes :

– Sp ∈ Neigp ∪ {C,D}. Initialement, la variable Sp est ´egale `a C (Clean) pour signifier que p n’est travers´e par aucun parcours : p attend d’ˆetre visit´e par un nouveau parcours (i.e., il attend de recevoir le jeton pour la premi`ere fois). Lorsque Sp ∈ Neigp, cela signifie que p participe au parcours courant et d´esigne le processeur Sp comme un successeur courant de p dans le parcours. Enfin, Sp = D (Done) signifie qu’un parcours est pass´e par p, que les visites de ce

parcours `a partir de p sont termin´ees et que p est en attente de nettoyage.

– P arp. P arp ∈ Neigp pour p = r et P arp =⊥ pour p = r. P arp est utilis´e pour pointer le p`ere de p dans le parcours courant, i.e., le voisin qui lui a envoy´e la premi`ere fois le jeton. Les variables P ar permettent de garder une trace de l’arbre en profondeur suivi par le parcours `a partir de la racine (les variables P ar ne sont jamais r´einitialis´ees). Par d´efinition, r n’a jamais de p`ere dans un parcours (r est l’initiateur), donc P arr est une constante ´egale `a ⊥.

Contrai-rement `a la variable Sp, la variable P arp n’est pas essentielle pour effectuer un parcours en profondeur, par exemple, un protocole de parcours en profondeur non-tol´erant aux fautes et n’utilisant pas de pointeur p`ere est pr´esent´e dans la th`ese de Petit [Pet98]. Cependant, nous avons choisi d’utiliser le pointeur p`ere pour avoir une phase de visite similaire aux protocoles instantan´ement stabilisants de parcours en profondeur pr´esent´es dans la suite de cette th`ese. D´ecrivons maintenant, `a partir de l’exemple fourni figure 5.3.3, le comportement de notre proto-cole DFS0 (algorithmes 5.3.1 et 5.3.2). Initialement, le syst`eme est dans une configuration o`u

(Requestr = Out) ∧ (∀p ∈ V , Sp = C). Supposons que la racine, r, rec¸oive une requˆete (i.e.,

Requestr := W ait) via l’ex´ecution de la r`egle externe IR. Suite `a cette requˆete, le syst`eme se

retrouve dans une configuration similaire `a la configuration (i) de la figure 5.3.3. Dans cette configu-ration, l’action de d´emarrage, i.e., la r`egle F de r, est l’unique r`egle activable du syst`eme. r ex´ecute donc sa r`egle F dans le premier mouvement ((i)→ (ii)) : r amorce une phase de visite en d´esignant

comme successeur son voisin minimal dans l’ordre localr(i.e., r cr´ee un jeton et l’envoie `a ce voi-sin) et en affectant In `a Requestr pour signifier `a l’application que sa requˆete a ´et´e prise en compte. Dans le mouvement suivant ((ii) → (iii)), le successeur d´esign´e p pointe son p`ere (r) avec sa

va-riable P arp et prolonge la phase de visite en d´esignant comme successeur son voisin non visit´e q minimal dans l’ordre localp : p rec¸oit le jeton de r puis l’envoie `a q (r`egle F ). La phase progresse ainsi s´equentiellement dans la profondeur du r´eseau jusqu’`a atteindre un processeur q n’ayant plus aucun voisin non visit´e (configuration iv). Lorsqu’il est atteint, q pointe son p`ere et affecte la valeur

46 Parcours en profondeur instantan´ement stabilisants Algorithm 5.3.1 AlgorithmeDFS0 pour p = r

Entr´ee-sortie : Requestp∈ {W ait,In,Out} initialis´e `a Out ;

Entr´ee : N eigp: ensemble des voisins (localement ordonn´e) ;

Constante : P arp=⊥ ;

Variable : Sp∈ Neigp∪ {C,D} initialis´e `a C ;

Macro :

N extp = (q = min≺p{q∈ Neigp:: Sq = C}) si q existe, D sinon ;

Pr´edicats : Leaf(p) ≡ (∀q ∈ Neigp:: (P arq = p) ⇒ (Sq= C)) F orward(p) ≡ (Sp= C) Backward(p) ≡ (∃q ∈ Neigp:: Sp= q ∧ Sq= D) Clean(p) ≡ (Sp= D) ∧ Leaf(p) R`egles : Phase de Visite :

F :: F orward(p) ∧ (Requestp= W ait) → Sp:= Nextp; Requestp:= In ;

B :: Backward(p) → Sp:= Nextp;

Phase de Nettoyage :

C :: Clean(p) → Sp:= C ; Requestp:= Out ;

son successeur courant (r`egle F dans le mouvement (iv) → (v)). Dans le mouvement suivant, le

p`ere de q affecte lui-aussi la valeur D `a sa variable Sq (il renvoie le jeton `a son p`ere) car il n’a plus de voisin non visit´e (r`egle B). Le jeton remonte ainsi en suivant les pointeurs p`eres jusqu’`a atteindre un processeur ayant encore des voisins non visit´es (le processeur r dans la configuration vii). Le processeur d´esigne alors un nouveau successeur parmi ses voisins non visit´es et lui envoie le jeton en ex´ecutant sa r`egle B (cf. r dans le mouvement (vii)→ (viii)). Ainsi, la phase de visite reprend `a

par-tir de ce nouveau succcesseur. En parall`ele de la remont´ee du jeton, la phase de nettoyage s’amorce. Le nettoyage est effectu´e `a partir des feuilles de l’arbre couvrant calcul´e (r`egle C). Un processeur

p = r peut se nettoyer lorsque tout son sous-arbre a ´et´e nettoy´e et que plus aucun de ses voisins ne

participe `a la phase de visite (∀q ∈ Neigp, Sq ∈ {C,D}). Par ce m´ecanisme, la phase de visite finit

par terminer `a la racine (mouvement (ix) → (x)). La phase de nettoyage se termine par la suite `a

la racine (mouvement (xi) → (xii)) : la racine se nettoie, via la r`egle C, apr`es que tous ses voisins

se sont nettoy´es (mouvement (xi) → (xii)). La r`egle C de la racine est aussi utilis´ee pour signifier

`a l’application que le parcours demand´e est termin´e et que le syst`eme est `a nouveau en attente de requˆete (i.e., Requestr := Out).

Le protocole DFS0 (cf. algorithmes 5.3.1 et 5.3.2) est asymptotiquement optimal en temps

d’ex´ecution (O(n) mouvements). Il faut noter que la borne inf´erieure du temps d’ex´ecution de tout parcours en profondeur dans un r´eseau enracin´e quelconque conc¸u pour un environnement sans faute et ´ecrit dans le mod`ele `a ´etats est exactement 2(n − 1) mouvements (le nombre de mouvements

n´ecessaires pour parcourir les arˆetes de l’arbre couvrant dans les deux sens) et 2(n− 1) rondes (le

parcours est s´equentiel, i.e. son degr´e de parall´elisation est 1). Un protocole ayant exactement cette complexit´e en temps d’ex´ecution peut ˆetre facilement r´ealis´e : il suffit de remplacer la phase de net-toyage par un m´ecanisme utilisant deux couleurs (un tel protocole peut ˆetre trouv´e dans la th`ese de Petit, [Pet98]). Cependant, nous avons choisi de pr´esenter le protocoleDFS0 car sa phase de visite

sera r´eutilis´ee de mani`ere quasi identique dans les protocoles instantan´ement stabilisants de parcours en profondeur pr´esent´es dans la suite de cette th`ese.

Nous allons maintenant pr´esenter deux solutions instantan´ement stabilisantes pour le probl`eme de parcours en profondeur dans un r´eseau enracin´e quelconque. Ces deux solutions ont la particularit´e de fonctionner avec un d´emon distribu´e in´equitable. La premi`ere solution est bas´ee sur des listes d’identit´es. La seconde utilise un principe de question/r´eponse pour remplacer les listes d’identit´es.