Je ne suis pas d'accord avec vous. Pourquoi ne peut on pas passer de P1 à P3 avec le code de Thomas?
Il suffit par exemple de penser au scénario suivant :
- P1 possède la main, il fait une itération de sa boucle principale (`while(true)`). À la fin de la boucle, on a donc turn = 2; C1 = 1; C2 = 1; C3 = 1.
- P1 perd la main et elle est donné à P3. Comme les deux autres processus n'ont pas encore l'intention d'entrer en section critique (C1 = 1; C2 = 1), la condition de la boucle externe de la section non critique est sautée et P3 rentre en section critique.
On est donc passé de P1 à P3 sans passer par P2. Quel est le problème?
Personnelement, je vois les choses ainsi:
Les variables Ci indiquent si un processus a l'intention d'entrer en section critique. Si un processus i a l'intention d'entrer en section critique, alors Ci = 0, sinon Ci = 1. Cela étant, un processus ne peut pas entrer en section critique si d'autres processus ont aussi l'intention d'y entrer, ou si un autre s'y trouve déjà. C'est donc la raison d'être de la première boucle de la section non-critique. Elle permet à un processus de temporairement renoncer à l'exclusion mutuelle avant de réessayer.
Maintenant, si on ne s'en tient qu'aux variables Ci, alors un deadlock est possible en cas de symétrie parfaite des instructions. Pour pallier ce problème, on introduit une variable Turn qui permet de rompre la symétrie.
Considérons le cas de deux processus. On débute avec C1, C2, Turn = 1. En cas de symétrie parfaite des instructions, les deux processus vont aboutir aux boucles internes `while (Turn == 2)` (resp. `while (Turn == 1)`). Comme on a Turn 1, le premier processus va passer outre cette boucle tandis que le second va s'y retrouver piéger. Par ailleurs, comme juste avant le processus 2 a retiré son intention d'entrer en section critique (C2 = 1), le premier peut quitter la boucle externe et entrer en section critique. Bref, la variable Turn a avant tout pour effet de briser la symétrie.
Il est aussi indispensable de noter, contrairement à ce que disait Mat et Xeon, que cette variable n'induit PAS une alternance stricte entre les processus. En effet, lorsqu'un processus a terminé une itération, aucune contrainte ne l'empêche d'aussitôt réentrer en section critique s'il conserve la main. Le fonctionnement correct de l'algorithme dépend donc du fait que chaque processus finit toujours par progresser à un moment ou un autre, condition dépendante du gestionnaire de processus qui est supposé garantir l'équité.
Citation (xeon)
turn permet de faire """"""""dormir""""""" le processus tant que ce n'est pas a son tour d'entrer dans la section critique
Malgré les guillemets, je ne peux pas m'empêcher de rebondir la dessus

Les processus ne sont pas endormis, ils sont en attente active. Lorsqu'un processus a la main et qu'il est piégé dans une boucle `while (Turn != i)`, des cycles CPUs sont inutilement bouffés à vérifier sans cesse la condition (qui ne peut évidemment pas changer tant que ce processus garde la main), ce qui est d'ailleurs bien laid.