Ecole NAtioNALE des Sciences de l’InformAtique
A. U. : 2018/2019
Proposition de correction
Devoir Surveillé
Systèmes d’Exploitation & Programmation Concurrente
Classes
Durée
: II2
: 2h00
Date
: 16/11/2018
Nb. Pages
: 4
Documents : Non autorisés
Enseignants: F. Najjar, N. Chakchouk, H. Elhedhili & Y. Kadri
Note: On demande des réponses brèves mais claires, précises et concises
(Correction sur 21 ! 1 point en plus pour exercice 3 ordonnancement)
Exercice 0. Question de cours (1 point)
Dans un contexte de concurrence interprocessus, dire en quoi consiste le problème de
famine (starvation)? Précisez la différence avec l’interblocage (deadlock) ?
Problème de famine apparaît quand des processus (faible priorité) attendent infiniment
une ressource partagé sans pouvoir y accéder ! alors que l’interblocage bloque tous les
processus et ne puissent jamais avancer !
1
Exercice 1. Fork (3 points –1+1+1)
On considère le code C suivant :
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main()
{
int i;
for(i=0;i<4;i++)
if(fork())break;
printf("Mon nom est <%c>",'A'+i);
return(EXIT_SUCCESS);
}
1) Donnez l’arborescence des processus engendrés par ce programme.
2)
i=0
i=1
i=2
i=3
i=4
P1
P11
P111
P1111
P11111
1
1/4
3) Quel affichage possible peut engendrer l’exécution de ce programme ?.
Mon nom est A Mon nom est B
Mon nom est C
Mon nom est D Mon nom est E
4) Modifiez ce programme de façon à ce que les processus fassent leur affichage par ordre alphabétique
inversé du nom.
1
1
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main()
{
int i;
for(i=0;i<4;i++)
if(fork())break;
wait (NULL);
printf("Mon nom est <%c>",'A'+i);
return(EXIT_SUCCESS);
}
Exercice 2. Concurrence et synchronisation (4 points –0,75+0,75+1+1,5)
Soient les deux processus PA et PB partageant une variable k initialisée comme suit :
Publicité
public int k=1;
Processus PA
int main ()
{ int i;
1. i=k;
2. i=i+1;
3. k=i;
4. printf("PA avec k=%d\n",k);
Processus PB
int main ()
{ int j;
1. j=k;
2. j=j+4;
3. k=j;
4. printf("PB avec k =%d\n",k);
...
}
...
}
1) Rappelez (en général) quand peut-on avoir des résultats corrects d’exécution concurrente
(entrelacée) de deux processus?
Les résultats corrects de PA//PB sont compris dans soit les résultats de PA ;PB
ou PB ;PA c’est-à-dire PA avec k=2, PB avec k=6 (2,6) ou encore PB avec k=5, PA
avec k=6 (5,6). Cq. k=6
0,75
2/4
2) Les résultats suivants sont-ils possibles ? corrects ? Justifiez vos réponses ?
R1
R2
R3
PA avec k=2
PB avec k =2
PA avec k =2
PB avec k=6
PA avec k =5
PB avec k=2
R1 (2,2) possible et non correcte :
o Exécution de PA1 ; PA2 ; PA3 ; PA4 ; PB1 ; PB2 ; PB3 ; PB4
o (2,2) différent des (2,6) et (5,6).
R2 (2,6) possible et correcte car équivalente à PA ;PB
R3 (5,2) non possible et non correcte
0,25
0,25
0,25
o car k est incrémentée et donc la 2ème valeur est supérieure ou
égale !!!
3) En donnez, dans chaque cas, un entrelacement d’exécution des deux processus qui génère une
réponse, qui soit
a) possible et correcte.
PB ;PA (5,6) possible et correcte
0,5
b) possible et non correcte.
(5, 5) c-à-d PA1 ;PA2 ;PA3 ; PB1 ;PB2 ;PB3 ;PB4 ; PA4. (6,6) c-à-d
PB1 ;PB2 ;PB3 ; PA1 ;PA2 ;PA3 ;PA4 ; PB4
0,5
4) Afin de garantir tout le temps des résultats corrects, dire que peut-on proposer ? Modifiez le
code des processus PA et PB et précisez vos variables partagées (avec initialisation) ?
public int k=1;
public semaphore Mutex=1 ;
0,5
Processus PA
Processus PB
int main ()
{ int i;
int main ()
{ int j;
0,5 (P et V)
P(Mutex);
i=k;
i=i+1;
k=i;
printf("PA avec k=%d\n",k);
0,5 (P et V)
Publicité
P(Mutex);
j=k;
j=j+4;
k=j;
printf("PB avec k =%d\n",k);
V(Mutex);
...
}
V(Mutex);
...
}
3/4
Remarque : SC contient un read sur k (i=k), un write sur k (k=i) et enfin un
read sur k (printf(…k) ;). En cq. V(Mutex) doit être après printf pour ne pas
avoir (6,6) qui est différent des deux résultats corrects (2,6) et (5,6) !!
Exercice 3 : Ordonnancement (6 points --1+1,5(+0 ,75 en plus)+2,5 (+0,25 en plus) +1)
On considère l’ensemble des processus suivants :
Processus
Date d'arrivée
Temps estimé –TE Priorité
P1
P2
P3
P4
7h00
7h00
7h03
7h10
10mn
15mn
8mn
18mn
2
3
4
5
1) Les algorithmes d’ordonnancement basés sur des priorités peuvent-ils engendrer le problème de
famine des processus à faible priorité ?. Comment peut-on éviter ce problème ?
Par ordonnancement pour avoir périodiquement une équité
1
2) On suppose qu’on utilise un algorithme d’ordonnancement basé sur la priorité (la plus grande
valeur signifie la plus haute priorité).
Donnez le diagramme de Gantt pour l’ordonnancement priorité (statique) avec préemption. En déduire le temps de
réponse de chaque processus et le temps de réponse moyen.
0—P2—3—P3—10—P4—28—P3—29—P2—41—P1—51
1,5 (0,25/transition)
Tps de réponse –TR TR(P1)=51mn ; TR(P2)=41mn ; TR(P3)=26mn ;
TR(P4)=18mn
TRmoyen = (51+41+26+18)/4 = 40mn
0,75
3) On souhaite maintenant que la priorité des processus soit dynamique au cours du temps. Ainsi,
pour calculer la priorité d’un processus, on utilise la formule suivante :
Priorité = (T_Att+TE_Restant) /TE
Où
T_Att correspond au temps d’attente d’un processus depuis sa dernière exécution.
TE_Restant = TE – Temps d’exécution courant.
Avec les hypothèses suivantes :
Au démarrage, les priorités des processus sont égales à leurs priorités statiques initiales
(indiquées dans le tableau).
4/4
Les priorités sont recalculées à chaque 5mn. Pour les autres temps, on prend la priorité
précédente.
Lors des calculs des priorités, on arrondira comme suit :
si E(2X)=2E(X) alors E(X) sinon E(X) +1 où E est la fonction partie entière.
En cas d’égalité des priorités, on choisit le processus qui attend depuis le plus longtemps.
a) Donnez le diagramme de Gantt de l’ordonnancement préemptif des processus par priorité
dynamique en précisant l'évolution des priorités des différents processus. En déduire le temps
de réponse de chaque processus et le temps de réponse moyen.
2,75 (1,25 tableau (80,125+0,25) + 1,5 DGantt (13 transitions 0,115)
process Tcpu
P1
p2
P3
Publicité
P4
10
15
8
18
Prio
init
2
3
4
5
t=5
t=10
t=15
t=20
t=25
t=30
t=35
t=40
t=45
2
1
1
--
1
1
1
5
1
2
2
1
2
0
3
1
2
1
0
1
---
1
1
2
1
1
0
0
2
1
0
--
0
0-P2-3-P3-5-P1-10-P4-15-P2-20-P3-25-P1-30-P4-35-P2-40-P3-41-P4-45-P2-47-P4-51
b) Ce procédé permet-il de résoudre le problème de famine? Expliquer
Exercice 4. Synchronisation du problème H2O (6 points –1,5+2+1+1,5)
On souhaite pratiquer les problèmes de synchronisation, vu en cours, dans la chimie. Comme exemple
classique, on prend une molécule d’eau, qui est formée de 2 atomes d’hydrogènes (H2) et un atome
d’oxygène (O). On souhaite écrire du code qui profite d’une synchronisation interprocessus à base de
sémaphores pour le problème de construction de molécules d’eau (H2O). La solution à proposer
doit modéliser la récupération en même temps de deux atomes H (H2) et un atome O afin de créer
une molécule H2O.
1) Identifiez et donnez les différents processus en synchronisation ? A quel(s) type(s) de problème(s)
de synchronisation appartient-il ? expliquez brièvement.
1,5
H |
H
| H20
O |
Problème de Producteurs/consommateur et RDV :
5/4
Solution 1 : 3 classes de processus dont 1 classe Hydrogene, 1 classe
Oxygène et une 3ème classe H2O. En d’autres termes, 3 producteurs
Publicité
(H2+0) et un consommateur (H2O) et RDV entre 3 processus H H et O
Solution 2 : 2 classes de processus dont 1 classe Hydrogene, 1 classe
OxyReady avec combinaison H2O. En d’autres termes, 2 producteurs H et
H et un consommateur O et RDV entre 2 H
2) En indication, on propose d’utiliser (au moins) les variables globales suivantes :
Semaphore Hyd, Oxy; //obligatoires
//Hyd sert à marquer la présence d’un atome H
// Oxy sert à marquer la présence d’un atome O
a) Donnez les valeurs initiales de ces variables ? justifiez.
Semaphore Hyd=Oxy= 0 ; //Sémaphore de blocage pr RDV et P/C 0,5
b) Ecrire les différents codes C correspondant à la formation des molécules d’eau.
Hydrogene()
{
While (True) {
0,75
V(Oxy) ; //Producteur de H
P(Hyd); //RDV avec un 2nd H
}
}
OxyReady()
{
While (True) {
0,75
P(Oxy); //Cons. de H
P(Oxy); //Cons. du 2nd H
makeWater(); //H2O
V(Hyd);
V(Hyd);
}
}
3) Dérouler l’exécution du scénario suivant : deux H arrivent l’un après l’autre puis deux O arrivent
en même temps (c-à-d H1(1) ; H2 (2); O1(3) ; O2(3); … avec Xi(t) signifie l’atome X (dans {H,
O}) de numéro i, arrivé au temps t) ? Conclure ?.
This is dangerous, since it may lead to starvation. If two H’s arrive, then the
value of the Oxy semaphore will be 2. If two O’s arrive, then they can each
decrement Oxy, before either can decrement it twice. So no water is made, even
1
though enough atoms have arrived!!
4) Afin d’éviter le problème de famine modifiez la solution proposée par le rajout d’un autre
sémaphore en précisant son initialisation.
6/4
The fix is to put a lock acquire before the first line in OxyReady, and a lock
release after the two V(Hyd)’s. This way, only one oxygen looks for waiting H’s
at a time -- if there aren’t enough H’s for the first oxygen, there won’t be enough
for any of the later oxygens either.
Semaphore Hyd=Oxy= 0 ; //Sémaphore de blocage pr RDV et P/C
Semaphore Mutex = 1 ; //Exclusion mutuelle sur attente de 2 H
0,5
Hydrogene()
{
While (True) {
V(Oxy) ; //Producteur de H
P(Hyd); //RDV avec un 2nd H
}
}
OxyReady()
{
While (True) {
P(Mutex) ;
1
P(Oxy); //Cons. de H
P(Oxy); //Cons. du 2nd H
makeWater(); //H2O
V(Hyd);
V(Hyd);
V(Mutex) ;
}
}
7/4
8/4