Vous êtes sur la page 1sur 2

TP de Systèmes d’exploitation


Section Critique – Exclusion Mutuelle
L3–UPJV

Septembre 2020

Dans le dernier exercice du premier TP, voir figure (2), nous avons constaté que l’accès
concurrent par deux threads à une variable commune provoquait un comportement anormal et
conduisait à des calculs faux. Ce phénomène est connu sous le nom de situation de compétition
(race condition) : si la modification de la variable commune n’est pas atomique, i.e. qu’elle
nécessite plusieurs opérations qui peuvent être interrompues par le concurrent, alors la modifi-
cation est une section critique, et nous devons mettre en œuvre des mécanismes qui garantissent
qu’un seul thread accède à cette ressource commune à la fois, pendant que les autres attendent
que la ressource soit libérée. C’est ce que l’on appelle l’exclusion mutuelle.
En cours, nous avons vu une solution logiciel basée sur une seconde variable qui assure l’ex-
clusion mutuelle, voir figure (1a). L’objectif de ce nouvel exercice est de voir d’autres solutions
logicielles à ce problème, qui passera par l’introduction de nouvelles variables qui permettent
de contrôler l’accès à la ressource commune.

Exercices 1 Verrous logiciels


1. En utilisant un automate, refaites la preuve que la solution (1a) assure l’exclusion mu-
tuelle.
2. Vérifier, par un automate, si la seconde version de la figure (1b), qui utilise deux variables
(en fait un tableau de deux éléments), est correcte.
3. Vérifier, par un automate, si la troisième version de la figure (1c), qui utilise aussi deux
variables, est correcte.
4. On considère à nouveau la version avec un jeton, figure (1a). On remplace la condition
d’itération de i, i<n, par i<(n*(k+1)).
(a) Combien d’itérations effectuera le thread 0 ? Le thread 1 ?
(b) Il y aura il un problème lors de l’exécution du programme ? Lequel ?
5. Reprendre le code de la figure (1c) en rajoutant une troisième variable tour qui indique
quel thread peut accéder au compteur (en modifiant bien sûr la condition d’entrée en
section critique) ?
6. Vérifier l’exclusion mutuelle par un automate.
7. A t-on le même problème que pour la première version si les nombres d’itération des
threads sont différents ?
while (i<n) { while (i<n) {
while (i<n) {
while (a[1-k]); a[k]=1;
while (jeton==1-k);
a[k]=1; while (a[1-k]);
compteur=compteur+1;
compteur=compteur+1; compteur=compteur+1;
jeton=1-k;
a[k]=0; a[k]=0;
i=i+1;
i=i+1; i=i+1;
}
} }
(a) Solution avec un jeton
(b) Solution avec deux variables 1 (c) Solution avec deux variables 2

Figure 1 – Tentatives de solutions logicielles.

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <pthread.h>
5
6 unsigned int n;
7 unsigned int compteur=0;
8
9 void *inc(void *arg) {
10 unsigned int i=0;
11 int k=atoi((char *)arg);
12
13 printf("Thread %d lance\n",k);
14
15 while (i<n) {compteur=compteur+1; i=i+1;}
16 }
17
18 int main(int argc,char *argv[]) {
19 int i,j;
20 pthread_t t1, t2;
21 if (argc!=2) {
22 fprintf(stderr,"usage %s n (n>0)\n",*argv);
23 exit(2);
24 }
25
26 n=atoi(argv[1]);
27 printf("sizeof(int)=%d\n",sizeof(int));
28 pthread_create(&t1,NULL,inc,"0");
29 pthread_create(&t2,NULL,inc,"1");
30 pthread_join(t1,NULL);
31 pthread_join(t2,NULL);
32 printf("compteur=%u\n",compteur);
33 }

Figure 2 – Incrémentation concurrente d’un compteur.

Vous aimerez peut-être aussi