Algorithme du Jeton
entrer_SC(nbProc){
while (turn != nbProc);
}
libérer_SC(nbProc){
turn = 1 – nbProc;
}
Preuve
On va prouver par l'absurde que cet algorithme vérifie la propriété
d'exclusion mutuelle.
Exclusion Mutuelle : Deux processus ne peuvent pas se trouver dans la SC
en même temps. Supposons alors que les processus P0 et P1 sont dans la SC.
P0 dans SC => turn = 0
impossible
P1 dans SC => turn = 1
Ainsi, la propriété d'exclusion mutuelle est vérifiée.
Exercice 1 (4 = 2+2)
Initialisations
int CANDIDAT[2]; // Peut prendre les valeurs 0 et 1
int PRIOR = 1; // Variable partagée
for (int i = 0; i<2; i++) CANDIDAT[i] = 0;
Processus 0 Processus 1
while (1){ while (1){
1 CANDIDAT[0] = 1; CANDIDAT[1] = 1;
2 while(CANDIDAT[1]&&PRIOR==1); while(CANDIDAT[0]&&PRIOR==0);
Section_Critique(); Section_Critique();
3 PRIOR = 1; PRIOR = 0;
4 CANDIDAT[0] = 0; CANDIDAT[1] = 0;
Section_Non_Critique(); Section_Non_Critique();
} }
1. L'exclusion mutuelle
P0 P1
1 CANDIDAT[0] = 1
2 CANDIDAT[1]&&PRIOR==1 ? FAUX
Section Critique
1 CANDIDAT[1] = 1
2 CANDIDAT[0]&&PRIOR==0 ? FAUX
Section Critique
2. L'absence d'interblocage
Preuve :
Initialisations
init (s_inc,0) //Initialisation du sémaphore s_inc
init (s_dec,0) //Initialisation du sémaphore s_dec
init (mutex,1) //Initialisation du sémaphore mutex
int data = 0 //Variable partagée
Processus P1 Processus P2
tant_que (vrai) tant_que (vrai)
up(s_dec) up(s_inc)
down(s_inc) down(s_dec)
down(mutex) down(mutex)
data <- data +1 data <- data -1
write ("P1 : "+data); write ("P2 : "+data);
up(mutex) up(mutex)
fin tant_que fin tant_que
quelles sont les valeurs possibles que peut prendre la variable data? Justifier
votre réponse.
Grâce aux deux sémaphores, s_dec et s_inc, cet algorithme fait en sorte
qu'un processus ne puisse pas changer data deux fois de suite. Ainsi, si c'est P1
qui commence en premier, alors data va toujours passer de 0 à 1 à 0..., et si c'est
P2 qui s'exécute en premier, alors data prendra les valeurs 0, -1, 0...
. Exercice 3 (6 = 3+1+2)
Dans chaque bureau de poste régional, trois agents procèdent au tri (fonction
trier_courrier_régional). Si l'un des agents termine avant les autres, il doit les
attendre (fonction attendre). Une fois que tous les agents ont terminé, un unique
agent doit être désigné pour se rendre au bureau de poste principal (fonction
designer_transporteur).
Chaque réponse doit être précédée par une partie initialisations qui doit
définir les variables partagées et les sémaphores utilisés.
Initialisations :
nbAgent = 0;
semaphore mutex = 1;
semaphore rdv = 0;
attendre (num, nbAgentTotal){
down(mutex);
nbAgent++;
if ( nbAgent < nbAgentTotal){
up(mutex);
down(rdv);
}else{
up(mutex);
for ( int i = 0; i < nbAgentTotal ; i++){
up(rdv);
}
}
Initialisations :
nbAgent = 0;
semaphore mutex = 1;
désigner_transporteur (num, nbAgentTotal){
down(mutex);
nbAgent++;
if ( nbAgent < nbAgentTotal){
up(mutex);
exit( );
}else{
up(mutex);
}
Initialisations :
nbAgent = 0;
semaphore mutex = 1;
semaphore rdv = 0;
agent (num){
trier_courrier_régional();
attendre(num, nb_reg);
désigner_transporteur(num, nb_reg);
trier_courrier_principal();
attendre(num, nb_princ);
désigner_transporteur(num, nb_princ);
expédier_courrier();
}
Bon Travail