0% ont trouvé ce document utile (0 vote)
37 vues80 pages

Examen Système d'Exploitation 2023

Transféré par

Aymen Raki
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
37 vues80 pages

Examen Système d'Exploitation 2023

Transféré par

Aymen Raki
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Examen système d’exploitation Département d’informatique, Université de Bouira

1ère Année Master ISIL (2017/2018) Durée : 1h30 Documents non autorisés

Exercice 1 (3 pts) :
1. Qu’est-ce qu’un PCB et de quoi est-il composé ? (0,5 pt)

PCB est une structure de données particulière appelée bloc de contrôle de processus (PCB :
Process Control Bloc) et dont le rôle est de reconstituer le contexte du processus.

PCB est composé de l'ensemble des informations dynamiques qui représente l‘état d‘ exécution
d'un processus. Il contient aussi des informations sur l'ordonnancement du processus (priorité du
processus, les pointeurs sur les files d'attente)

2. L'appel système fork() est le moyen pour créer des processus, par duplication d'un processus
existant. Expliquer comment distinguer entre le processus père et le processus fils. (0,5 pt)
Pour distinguer le processus père du processus fils on regarde la valeur de retour de fork(), qui peut
être:
 La valeur 0 dans le processus fils.
 Positive pour le processus père et qui correspond au PID du processus fils.
 Négative si la création de processus fils a échoué ;
3. Quelles critiques peut-on faire aux solutions de l'attente active et Peterson du problème de
l'exclusion mutuelle ?

Attente active : (1 pt)


1- Cette méthode n'assure pas l'exclusion mutuelle
2- Susceptible de consommer du temps en bouclant inutilement.
Peterson : (1 pt)
1- La généralisation de cette solution aux cas de plusieurs processus est bien complexe.
2- Susceptible de consommer du temps en bouclant inutilement.
Exercice 2 (6 pts) :
On cherche à évaluer l'expression suivante
e := ((b-d) * (a+c) + (e*f)) / (a+c)
1. Réaliser un découpage en tâches de cette expression sans l'ajout de variables intermédiaires.
(2 pts)
t1: b = b - d
t2: a = a + c
t3: e = e * f
t4: b = b * a
t5: b = b + e
t6: e = b / a
2. En vous servant de la définition de la condition de Bernstein, donner le graphe de précédence
correspondant.
t1: {R(t1) = d, W(t1) = b};
Examen système d’exploitation Département d’informatique, Université de Bouira

t2: {R(t2) = c, W(t2) = a};


t3: {R(t3) = f, W(t3) = e}
t4: {R(t4) = a, W(t4) = b};
t5: {R(t5) = e, W(t5) = b};
t6: {R(t6) = b, a, W(t6) = e}

On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites : (2pts)
a) R (ti) ∩ W (tj) =∅
b) W (ti) ∩ R (tj) =∅ t2 t1 t3
c) W(ti) ∩ W (tj) =∅

Le graphe est le suivant t4

t5
t6

En se basant sur le graphe obtenu, réaliser la synchronisation des tâches (processus) en utilisant trois (03)
sémaphores S1, S2 et S3. (2pts)
Sémaphore S1=0, S2=0, S3=0

Pt1 (){ Pt2 (){ Pt3 (){ Pt4 (){ Pt5 (){ Pt6 (){
t1: b = b - d; t2: a = a + c; t3: e = e * f; P(S1); P(S1); P(S2);P(S2); P(S3);P(S3);
V(S1); V(S1); V(S3); V(S2); t4: b = b * a t5: b = b + e; t6: e = b / a;
} } } V(S2) V(S3) }
} }

Exercice 3 (7 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du buffer et le place dans la ZoneC où il
peut le consommer. Ce problème induit plusieurs types de contraintes de synchronisation qui sont:
1. Un producteur ne doit pas produire, ni déposer le message dans le buffer quand il n y a plus de
place pour déposer ce qu’il a produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
- Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.
Semaphore Mutex = 1, Plein = 0, Vide=n ; Message tampon[];
Producteur (){ Consommateur (){
Message m ; Message m ;
Tantque Vrai faire Tantque vrai faire
P(Vide); P(Plein);
m = creermessage() ; P(Mutex);
P(Mutex) ; m = LectureTampon();
EcritureTampon(m); V(Mutex);
V(Mutex) ; V(Vide);
V(Plein); Fin Tantque
FinTantque }
}
Exercice 4 (4 pts) : Soit le programme ci-dessous :

# define N 100 for (i=0;i<N;i++) else {


int k = 0; t[i] = rand (); for(i=1;i<N;i++)
int main () { P = fork (); t [0]+= t[i];
float t[N]; if (P ==0) { waitpid (P ,NULL ,0);
int i; k=1; }
pid_t P for(i=0 ; i<N ; i++) printf ("processus%d, %f \n",k, t[0]);
if (t[0] < t[i]) return 0;
t[0]= t[i]; }
}

1- Que fait le "processus 0" et le "processus 1" dans le code ci-dessus? Expliquez. (3pts)
1- Le processus 0 (le père) initialise un tableau aléatoirement, exécute l'appel système fork, calcule la
somme des éléments du tableau dans t[0], attend la terminaison de son fils et affiche t[0].
Le processus 1 (le fils) calcule le maximum du tableau dans t[0] qui il affiche.
2- Y a-t-il un risque pour que les deux processus fournissent des résultats incohérents ? Expliquez. (1pt)
Remarque : les processus s’annoncent à la fin du code avant le return 0

2 Non, car les deux processus ont des espace de données différents (pas de variable partagée)

A. ABBAS 3 Bon courage


Département d’informatique, Université de Bouira
Examen du module : Système d’exploitation 2
ème
3 Année Licence SI (2022/2023) Durée : 1h30

Exercice 1 (5 pts) :

1. Quelle est la différence entre un processus lourd et un processus léger (thread) ?


Le processus lourd est créé par duplication (copie exacte du processus original) d'un processus existant.
Le deux processus lourd ne partage pas le même espace mémoire. (1 pt)
Le thread créateur et le thread créé partagent tous deux le même espace mémoire (1 pt)
2. Comment est implémenté le concept de moniteur sous le langage Java. (3pt)
 Les données du moniteur doivent être déclarées avec le mot clé privates pour que seules les
méthodes du moniteur accèdent à ces données,
 Les méthodes (ou procédures d'entrée) du moniteur doivent être déclarées avec le mot clé
synchronized pour qu'elles puissent s'exécuter en exclusion mutuelle,
 La classe Object fournit les méthodes wait() et notify() pour la synchronisation des threads.
Exercice 2 (8 pts) : Soit le programme ci-dessous :
# define N 100 for (i=0;i<N;i++) else {
int k = 0; t[i] = rand (); for(i=1;i<N;i++)
int main () { P = fork (); t [0]+= t[i];
float t[N]; if (P ==0) { waitpid (P ,NULL ,0);
int i; k=1; }
pid_t P for(i=0 ; i<N ; i++) printf ("processus%d, %f \n",k, t[0]);
if (t[0] < t[i]) return 0;
t[0]= t[i]; }
}
1 - Que fait le "processus 0" et le "processus 1" dans le code ci-dessus? Expliquez. (3 pts)
Le processus 0 (le père) 2
 initialise un tableau aléatoirement,
 exécute l'appel système fork,
 calcule la somme des éléments du tableau dans t[0],
 attend la terminaison de son fils
 affiche t[0].
b- Le processus 1 (le fils) 1
 calcule le maximum du tableau dans t[0]
 affiche t[0].
2 - Y a-t-il un risque pour que les deux processus fournissent des résultats incohérents ? Expliquez. (2pt)
Non, car les deux processus ont des espace de données différents (pas de variable partagée)
3. Réécrire le programme précédent en utilisant les threads à la place du processus lourd et la
synchronisation d'accès aux sections critiques. (3 pt)

#include <stdio.h> void* A(void* arg){ void* B(void* arg){


#include <stdlib.h> int i; int i;
#include <unistd.h> sem_wait(&s); sem_wait(&s);
#include <pthread.h> for(i=0 ; i<N ; i++) for(i=1;i<N;i++)
#include <semaphore.h> if (t[0] < t[i]) t [0]+= t[i];
#define N 100 t[0]= t[i]; printf ("Tread B, %f \n",t[0]);
int k = 0; printf ("Tread A, %f \n",t[0]); sem_post(&s);
float t[N]; sem_post(&s); }
sem_t s; }

Dr. A. ABBAS 1
Examen système d’exploitation Département d’informatique, Université de Bouira

int main () {
pthread_t t1,t2;
for (int i=0;i<N;i++) pthread_join(t1, NULL);
t[i] = rand (); pthread_join(t2, NULL);
sem_init(&s, 0, 1); return 0;
pthread_create (&t1, NULL, A, NULL); }
pthread_create (&t2, NULL, B, NULL);

Exercice 3 (7 pts): On veut effectuer en parallèle le produit de deux matrices B et C d’ordre n (n * n)


remplis par des valeurs aléatoire et le résultat est stocké dans A.
On a : Pour j = 0 à n-1 A[i,j] =k=0,n-1 B[i,k]*C[k,j] ;
 Écrire le programme qui calcule A on crée 10 threads. Chaque threads se charge de calculer
quelques lignes de la matrice résultat A.

#include <stdio.h> int main(){


#include <stdlib.h> pthread_t Thread[10];
#include <unistd.h> sem_init(&S,0,1);
#include <pthread.h> int i,j;
#include <time.h> for(i=0;i<taille;i++)
#include <semaphore.h> for(j=0;j<taille;j++){
#define taille 20 B[i][j]=rand()%2;//=1;
C[i][j]=rand()%2;//=1;
int T[taille]; A[i][j]=0;
float A[taille][taille]; }
float B[taille][taille]; for(i=0;i<taille;i++)
float C[taille][taille]; T[i]=-1;

sem_t S; for(i=0;i<10;i++){
pthread_create(&Thread[i],NULL,&produit,NULL);
void * produit(){ }
int i,j,k,ligne; for(i=0;i<10;i++){
i=0; pthread_join(Thread[i],NULL);
while(i<taille){ }
sem_wait(&S); for(i=0;i<taille;i++){
while(T[i]!=-1 & i<taille){ for(j=0;j<taille;j++)
i++; printf("%.0f ",A[i][j]);
} printf("\n");
T[i]=1; }
ligne=i; return 0;
sem_post(&S); }
for(j=0;j<taille;j++)
for(k=0;k<taille;k++)
A[ligne][j]+=B[ligne][k]*C[k][j];
i++;
}
}

Dr. A. ABBAS 2
Département d’informatique, Université de Bouira
Examen système d’exploitation L3-SI Durée : 1h00
Exercice 1 (4 pts) :
1. Quelles sont les inconvénients des solutions de l'attente active et Peterson du problème de
l'exclusion mutuelle ?
2. Attente active : (2 pt)
3. 1- Cette méthode n'assure pas l'exclusion mutuelle
4. 2- Susceptible de consommer du temps en bouclant inutilement.
5. Peterson : (2 pt)
6. 1- La généralisation de cette solution aux cas de plusieurs processus est bien complexe.
7. 2- Susceptible de consommer du temps en bouclant inutilement.
Exercice 2 (5 pts) :
On cherche à évaluer l'expression suivante
e := ((b - d) * (a+ c) + (e*f)) / (a+c)
1. Réalise un découpage en tâches de cette expression sans l'ajout de variables intermédiaires. 1pt
t1: b = b - d
t2: a = a + c
t3: e = e * f
t4: b = b * a
t5: b = b + e
t6: e = b / a
2. En vous servant de la définition de la condition de Bernstein, donner le graphe de précédence
correspondant. 2 pt
t1: R(t1) = {d}, W(t1) ={ b};
t2: R(t2) ={ c}, W(t2) = {a};
t3: R(t3) = { f}, W(t3) ={ e}
t4: R(t4) ={ a}, W(t4) = {b};
t5: R(t5) ={e}, W(t5) = {b};
t6: R(t6) ={b, a}, W(t6) = {e}

On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites :
a) R (ti) ∩ W (tj) =∅
b) W (ti) ∩ R (tj) =∅
c) W(ti) ∩ W (tj) =∅
t1 // t2
t1 // t3
t1 → t4 : t1 précéde t4 puisque le b de t4 est celui calculé par t1
t1 t5 : t1 ne précéde pas t5 puisque le b de t5 (W(t1) ∩ W (t5)= {b}) ce n'est pas celui calculé par t1
mais c'est celui de t4
t1 t6 : même chose t2 t1 t3
t2 // t3
t2 → t4
t2 // t5 t4 t4 → t5
t2→ t6 t4 t6
t3 // t4 t5
t3 → t5 t5 → t6
t3 t6 t6

Dr. A. ABBAS 1
Département d’informatique, Université de Bouira
Examen système d’exploitation L3-SI Durée : 1h00
3. En se basant sur le graphe obtenu, réaliser la synchronisation des tâches (processus) en utilisant trois (03)
sémaphores S1, S2 et S3. 2pts
Sémaphore S1=0, S2=0, S3=0
Pt1 (){ Pt2 (){ Pt3 (){ Pt4 (){ Pt5 (){ Pt6 (){
t1: b = b - d; t2: a = a + c; t3: e = e * f; P(S1); P(S1); P(S2);P(S2); P(S3);P(S3);
V(S1); V(S1); V(S3); V(S2); t4: b = b * a t5: b = b + e; t6: e = b / a;
} } } V(S2) V(S3)
} }

Exercice 3 (6 pts) :
Soit une route reliant la ville A et la ville B. Les règles de circulation sur cette route sont les suivantes:
1. Des voitures peuvent y circuler ensemble dans le sens A → B ou dans le sens B → A
(circulation alternée),
2. La route ne doit jamais être empruntée simultanément par deux voitures allant en sens inverse.
3. La priorité d'accès à la route est la même pour les deux sens.
On considère donc deux classes d’utilisateurs (processus) : voitures de A vers B (V_AB) et voitures de
B vers A (V_BA).
Question:
En utilisant les sémaphores, écrivez les algorithmes des fonctions de demande d’accès aux tronçons
acces_AB(), acces_BA() et des fonctions de sortie des tronçons AB_sort () et BA_sort() de façon à ce
que les processus V-AB et V-BA respectent les trois règles de circulation sur la route. Précisez
clairement vos déclarations et initialisations.
Solution:
Initialisation 2pts
int nbAB=0; //Compte le nombre de voitures allant de A vers B
int nbBA =0; entier (init à 0) Compte le nombre de voitures allant de B vers A
Sempahore route=1; // pour permettre que des voitures de sens contraire ne s'engagent pas dans la voie en
même temps.
Sempahore mutexAB=1;//pour protéger la mise à jour en exclusion mutuelle de la variable protégée nbAB
Sempahore mutexBA=1; //pour protéger la mise à jour en exclusion mutuelle de la variable protégée nbBA
Code des fonctions 1pt/fonction
Fonction acces_AB() { Fonction acces_BA () {
P(mutexAB); P(mutexBA);
nbAB++; nbAB++;
si (nbAB == 1) P(route); si (nbAB == 1) P(route);
V(mutexAB);} V(mutexBA);}
Fonction AB_sort () Fonction BA_sort () {
P(mutexAB); (mutexBA);
nbAB--; nbBA--;
si (nbAB == 0) V(route); si (nbBA == 0) V(route);
P(mutexAB);} (mutexBA);}
Exercice 4 (5 pts) :
Écrire un programme qui crée 5 processus fils, chaque fils affiche son PID et se termine. Le père devra
attendre la fin de ses 5 fils et afficher quel a été le premier et dernier processus qui a terminé.

#include <stdio.h>
#include <stdlib.h>

Dr. A. ABBAS 2
Examen système d’exploitation Département d’informatique, Université de Bouira

#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid_premier, pid_dernier;
int i,pid[5],status;
for(i=0;i<5;i++){
pid[i]=fork();
if (pid[i] == -1) {
// ERREUR
fprintf(stderr, "Impossible de créer un fils (%d)\n", i);
} else if (pid[i]==0) {
// FILS
printf("Fils %2d (PID=%d): Activé\n", i, getpid());
exit(0);
} else {
printf("Père : Activation du fils %2d\n", i);
}
}
pid_premier = wait(&status);
wait(&status);
wait(&status);
wait(&status);
pid_dernier = wait(&status);
printf("Premier processus a finir : %d\n", pid_premier);
printf("Dernier processus a finir : %d\n", pid_dernier);
return 0;
}

A. ABBAS 3 Bon courage


Département d’informatique, Université de Bouira
Examen système d’exploitation L3 SI (2018/2019) Durée : 1h30
Exercice 1 (2 pts) :
1. Dans quel(s) état(s) peut se retrouver un processus juste après sa préemption (interruption) ?
Éligible (ou prêt) (0.5 pt)
2. Le sémaphore est une technique permettant la synchronisation et l'accès en exclusion mutuelle à
des ressources critiques. Une variable de sémaphore est constituée d’une valeur V et d’une file
attente F.
a. Expliquer le rôle de la valeur V et de la file F.
La valeur V désigne le nombre d'autorisations d'accès à une section critique. (0,5 pt)
La file F est utilisée pour sauvegarder les processus bloqués par l'opération P(S) du
sémaphore. (0,5 pt)

b. Comment initialiser la valeur V.


La valeur du sémaphore est initialisée par le nombre d'unité de la ressource disponible
(nombre de ressources libres). (0.5 pt)
Exercice 2 (6 pts) : On cherche à évaluer l'expression suivante :
e := ((b - d) * (a+ c) + (e*f)) / (a+c)
1. Réalise un découpage en tâches de cette expression sans l'ajout de variables intermédiaires. 0.5pt
t1: b = b - d
t2: a = a + c
t3: e = e * f
t4: b = b * a
t5: b = b + e
t6: e = b / a
2. En vous servant de la définition de la condition de Bernstein, étudier l'activité parallèle des tâches
obtenues et donner le graphe de précédence correspondant 2.5pts
t1: R(t1) = {d}, W(t1) ={ b};
t2: R(t2) ={ c}, W(t2) = {a};
t3: R(t3) = { f}, W(t3) ={ e}
t4: R(t4) ={ a}, W(t4) = {b};
t5: R(t5) ={e}, W(t5) = {b};
t6: R(t6) ={b, a}, W(t6) = {e}

On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites :
a) R (ti)  W (tj) =
b) W (ti)  R (tj) =
c) W(ti)  W (tj) =

t1 // t2
t1 // t3
t1 → t4 : t1 précéde t4 puisque le b de t4 est celui calculé par t1
t1 t5 : t1 ne précéde pas t5 puisque le b de t5 (W(t1)  W (t5)= {b}) ce n'est pas celui calculé
par t1 mais celui de t4
t1 t6 : même chose

t2 // t3
t2 → t4 t2 t1 t3
t4 → t5
t2 // t5
t4 t6
t2→ t6
t4
t5 → t6
t3 // t4
t5
t3 → t5
t3 t6 t6

Dr. A. ABBAS 1
Département d’informatique, Université de Bouira
Examen système d’exploitation L3 SI (2018/2019) Durée : 1h30
3. En se basant sur le graphe obtenu, réaliser la synchronisation des tâches (processus) en utilisant trois
(03) sémaphores S1, S2 et S3. 3pts
Sémaphore S1=0, S2=0, S3=0
Pt1 (){ Pt2 (){ Pt3 (){ Pt4 (){ Pt5 (){ Pt6 (){
t1: b = b - d; t2: a = a + c; t3: e = e * f; P(S1); P(S1); P(S2);P(S2); P(S3);P(S3);
V(S1); V(S1); V(S3); V(S2); t4: b = b * a t5: b = b + e; t6: e = b / a;
} } } V(S2) V(S3) }
} }

Exercice 3 (8 pts) : On considère une route reliant la ville de Bouira et la station de Tikjda. Les règles
de circulation sur cette route sont les suivantes:
 Des voitures peuvent y circuler ensemble dans le sens Bouira → Tikjda ou dans le sens Tikjda
→ Bouira (circulation alternée),
 La route ne doit jamais être empruntée simultanément par deux voitures allant en sens inverse.
 La priorité d'accès à la route est la même pour les deux sens.
On considère donc deux classe d’utilisateurs : voitures de Bouira vers Tikjda (V-BT) et voitures de
Tikjda vers Bouira V-TB.

Question:
1. Quelle est la différence entre ce problème et le modèle de lecteurs/rédacteurs ? 1,5 pt
La différence est que dans le modèle lecteur/rédacteur
 on autorise qu’un seul rédacteur à la fois en train d’occuper la ressource partagée (fichier) alors que
dans ce problème, la ressource (la route) peut être occupée par plusieurs processus en même temps et ceci
pour les deux classes V-BT et V-TB. 1pt
 le lecteur ne peut pas commencé à lire si aucun rédacteur n'à déjà rédiger alors dans ce problème la
route est autorisée d'accès initialement pour le processus des deux classes V-BT et V-TB 0.5pt
2. En utilisant les sémaphores, écrivez les algorithmes des fonctions de demande d’accès aux
tronçons BTaccses () "Bouira vers Tikjda", TBaccses () "Tikjda vers Bouira" et des fonctions de
sortie des tronçons TBexit () et BTexit () de façon à ce que les processus V-BT et V-TB
respectent les règles de circulation sur la route. Précisez clairement vos déclarations et
initialisations.
Solution:
Initialisation 2,5
int nbTB=0; //Compte le nombre de voitures allant de Tikjda vers Bouira
int nbBT =0; entier (init à 0) Compte le nombre de voitures allant de Bouira vers Tikjda
Sempahore route=1; // pour permettre que des voitures de sens contraire ne s'engagent pas dans la
voie en même temps.
Sempahore mutexTB=1;//pour protéger la mise à jour en exclusion mutuelle de la variable protégée
nbTB
Sempahore mutexBT=1; //pour protéger la mise à jour en exclusion mutuelle de la variable protégée
nbBT
Code des fonctions 1pt/fonction

Fonction TBaccess () Fonction BTaccess ()


P(mutexTB); P(mutexBT);
nbTB++; nbTB++;
si (nbTB == 1) P(route); si (nbTB == 1) P(route);
V(mutexTB); V(mutexBT);

Fonction TBexit () Fonction BTexit ()


P(mutexTB); (mutexBT);
nbTB--; nbTB--;
si (nbTB == 0) V(route); si (nbTB == 0) V(route);
P(mutexTB); (mutexBT);

Dr. A. ABBAS 2
Département d’informatique, Université de Bouira
Examen système d’exploitation L3 SI (2018/2019) Durée : 1h30
Exercice 4 (4 pts) : Soit le programme ci-dessous :
# define N 100 for (i=0;i<N;i++) else {
int k = 0; t[i] = rand (); for(i=1;i<N;i++)
int main () { P = fork (); t [0]+= t[i];
float t[N]; if (P ==0) { waitpid (P ,NULL ,0);
int i; k=1; }
pid_t P for(i=0 ; i<N ; i++) printf ("processus%d, %f \n",k, t[0]);
if (t[0] < t[i]) return 0;
t[0]= t[i]; }
}
1- Que fait le "processus 0" et le "processus 1" dans le code ci-dessus? Expliquez. (3pts)
a- Le processus 0 (le père) 1
 initialise un tableau aléatoirement,
 exécute l'appel système fork,
 calcule la somme des éléments du tableau dans t[0],
 attend la terminaison de son fils
 affiche t[0].
b- Le processus 1 (le fils) 1
 calcule le maximum du tableau dans t[0]
 affiche t[0].
2- Y a-t-il un risque pour que les deux processus fournissent des résultats incohérents ? Expliquez. (1pt)
Non, car les deux processus ont des espace de données différents (pas de variable partagée)
Remarque : les processus s’annoncent à la fin du code avant le return 0

Dr. A. ABBAS 3
Corrigé examen système d’exploitation Département d’informatique

1ère Année Master ISIL (2019/2020) Durée : 1h Documents non autorisés

Questions de cours (3 pts) :


1. L'appel système fork() est le moyen pour créer des processus, par duplication d'un
processus existant. Expliquer comment distinguer entre le processus père et le processus fils.
Pour distinguer le processus père du processus fils on regarde la valeur de retour de fork(), qui
peut être: (2pt)
 La valeur 0 dans le processus fils.
 Positive (>0) pour le processus père et qui correspond au PID du processus fils.
 Négative si la création de processus fils a échoué ;
2. Dans quel(s) état(s) peut se retrouver un processus juste après sa préemption
(interruption) ?
Éligible (ou prêt) (1pt)

Exercice 1 (7 pts) :
On cherche à évaluer l'expression suivante :
c := ((a-c) + (e*f) / (a-c)) / ((a-c) * (a+c))
1. Réalise un découpage en tâches de cette expression. 2pts

t1: x = a-c t5 : e = x+e


t2: e = e*f t6 : x = x*y
t3: y = a+c t7: c = e/x
t4: e = e/x

2. En vous servant de la définition de la condition de Bernstein, donner le graphe de


précédence correspondant.
Désignation des variables lues et écrites de chaque tâche 1pts
t1: R(t1) = a,c W(t1) = x;
t2: R(t2) = f W(t2) = e;
t3: R(t3) = a,c W(t3) = y
t4: R(t4) = x W(t4) = e;
t5: R(t5) = x W(t5) = e;
t6: R(t6) = y, a W(t6) = x
t6: R(t7) = e, x W(t7) = c
On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites :
a) R (ti)  W (tj) =
b) W (ti)  R (tj) =
c) W(ti)  W (tj) =

Application des conditions de Bernstein aux tâches 3 pts


t1//t2 t2//t3 t3//t4 t4->t5 t5 -/->t6 t6 ->t7
t1//t3 t2->t4 t3//t5 t4-/->t6 t5 ->t7
t1->t4 t2-/->t5 t3->t6 t4-/->t7
t1->t5 t2//t6 t3-/->t7
t1->t6 t2-/->t7 t2 t1
t3
t1->t6
t1-/->t7
t4
Le graphe 1 pts t5 t6

t7
Corrigé examen système d’exploitation Département d’informatique

Exercice 2 (4 pts) : Soit le programme ci-dessous :

# define N 100
int k = 0; if (P ==0) { else {
int main () { k=1; for(i=1;i<N;i++)
float t[N]; for(i=0 ; i<N ; i++) t [0]+= t[i];
int i; if (t[0] < t[i]) waitpid (P ,NULL ,0);
pid_t P t[0]= t[i]; }
} printf ("processus%d, %f \n",k, t[0]);
for (i=0;i<N;i++) return 0;
t[i] = rand (); }
P = fork ();

1- Que fait le "processus 0" et le "processus 1" dans le code ci-dessus? Expliquez.
1- Le processus 0 (le père) 3pts
 initialise un tableau aléatoirement,
 exécute l'appel système fork,
 calcule la somme des éléments du tableau dans t[0],
 attend la terminaison de son fils et
 affiche t[0].
Le processus 1 (le fils) 1 pts
 calcule le maximum du tableau dans t[0]
 qui il affiche.
Exercice 3 (6 pts) :
Écrire un programme qui crée 10 processus fils, chaque fils affiche son PID et le PID de son
père et se termine. Le père devra attendre la fin de ses 5 fils et afficher quel a été le premier et
le deuxième processus qui a terminé.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid_premier, pid_ deux;
int i,pid[10],status;
for(i=0;i<10;i++) {
pid[i]=fork();
if (pid[i]==0) {// FILS
printf("Fils (PID=%d): du père (PID%d)\n", getpid(), getppid());
exit(0);// ce n'est pas break
}
}
pid_premier = wait(&status);
pid_deux = wait(&status);
wait(&status); wait(&status); wait(&status);
printf("Premier processus a finir : %d\n", pid_premier);
printf("Deuxième processus a finir : %d\n", pid_ deux);
return 0;
}
Corrigé examen système d’exploitation Département d’informatique

1ère Année Master ISIL (2019/2020) Durée : 1h Documents non autorisés

Questions de cours (3 pts) :


1. L'appel système fork() est le moyen pour créer des processus, par duplication d'un
processus existant. Expliquer comment distinguer entre le processus père et le processus fils.
Pour distinguer le processus père du processus fils on regarde la valeur de retour de fork(), qui
peut être: (2pt)
 La valeur 0 dans le processus fils.
 Positive (>0) pour le processus père et qui correspond au PID du processus fils.
 Négative si la création de processus fils a échoué ;
2. Dans quel(s) état(s) peut se retrouver un processus juste après sa préemption
(interruption) ?
Éligible (ou prêt) (1pt)

Exercice 1 (7 pts) :
On cherche à évaluer l'expression suivante :
c := ((a-c) + (e*f) / (a-c)) / ((a-c) * (a+c))
1. Réalise un découpage en tâches de cette expression. 2pts

t1: x = a-c t5 : e = x+e


t2: e = e*f t6 : x = x*y
t3: y = a+c t7: c = e/x
t4: e = e/x

2. En vous servant de la définition de la condition de Bernstein, donner le graphe de


précédence correspondant.
Désignation des variables lues et écrites de chaque tâche 1pts
t1: R(t1) = a,c W(t1) = x;
t2: R(t2) = f W(t2) = e;
t3: R(t3) = a,c W(t3) = y
t4: R(t4) = x W(t4) = e;
t5: R(t5) = x W(t5) = e;
t6: R(t6) = y, a W(t6) = x
t6: R(t7) = e, x W(t7) = c
On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites :
a) R (ti)  W (tj) =
b) W (ti)  R (tj) =
c) W(ti)  W (tj) =

Application des conditions de Bernstein aux tâches 3 pts


t1//t2 t2//t3 t3//t4 t4->t5 t5 -/->t6 t6 ->t7
t1//t3 t2->t4 t3//t5 t4-/->t6 t5 ->t7
t1->t4 t2-/->t5 t3->t6 t4-/->t7
t1->t5 t2//t6 t3-/->t7
t1->t6 t2-/->t7 t2 t1
t3
t1->t6
t1-/->t7
t4
Le graphe 1 pts t5 t6

t7
Corrigé examen système d’exploitation Département d’informatique

Exercice 2 (4 pts) : Soit le programme ci-dessous :

# define N 100
int k = 0; if (P ==0) { else {
int main () { k=1; for(i=1;i<N;i++)
float t[N]; for(i=0 ; i<N ; i++) t [0]+= t[i];
int i; if (t[0] < t[i]) waitpid (P ,NULL ,0);
pid_t P t[0]= t[i]; }
} printf ("processus%d, %f \n",k, t[0]);
for (i=0;i<N;i++) return 0;
t[i] = rand (); }
P = fork ();

1- Que fait le "processus 0" et le "processus 1" dans le code ci-dessus? Expliquez.
1- Le processus 0 (le père) 3pts
 initialise un tableau aléatoirement,
 exécute l'appel système fork,
 calcule la somme des éléments du tableau dans t[0],
 attend la terminaison de son fils et
 affiche t[0].
Le processus 1 (le fils) 1 pts
 calcule le maximum du tableau dans t[0]
 qui il affiche.
Exercice 3 (6 pts) :
Écrire un programme qui crée 10 processus fils, chaque fils affiche son PID et le PID de son
père et se termine. Le père devra attendre la fin de ses 5 fils et afficher quel a été le premier et
le deuxième processus qui a terminé.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid_premier, pid_ deux;
int i,pid[10],status;
for(i=0;i<10;i++) {
pid[i]=fork();
if (pid[i]==0) {// FILS
printf("Fils (PID=%d): du père (PID%d)\n", getpid(), getppid());
exit(0);// ce n'est pas break
}
}
pid_premier = wait(&status);
pid_deux = wait(&status);
wait(&status); wait(&status); wait(&status);
printf("Premier processus a finir : %d\n", pid_premier);
printf("Deuxième processus a finir : %d\n", pid_ deux);
return 0;
}
Département d’informatique, Université de Bouira

Examen système d'exploitation 3ième année SI 2019/2020


Documentation non autorisée durée: 1h

Exercice 1 (2 pts) :
1. Quelles sont les opérations d'un sémaphore qui s’exécutent d’une manière indivisible ?
Le test de la valeur du sémaphore, le changement de sa valeur et la mise en attente éventuelle
sont effectués en une seule opération atomique indivisible. C'est-à-dire les opérations P(S) et
V(S). 1pts
2. L'appel système fork() est le moyen pour créer des processus, par duplication d'un processus existant.
Expliquer comment distinguer entre le processus père et le processus fils.
Pour distinguer le processus père du processus fils on regarde la valeur de retour de fork(), qui
peut être:1pts
 La valeur 0 dans le processus fils.
 Positive pour le processus père et qui correspond au PID du processus fils
 Négative si la création de processus a échoué ;

Exercice 2 (8 pts) : On considère deux processus P1 et P2 concurrents.


Les codes des processus P1 et P2 sont les suivants:
P1 ( ) { P2 ( ) {
while(TRUE) while(TRUE)
printf("je suis le processus 1\n"); printf("je suis le processus 2\n");
} }
1- Synchroniser les deux processus à l'aide des sémaphores afin de montrer à l'écran la sortie suivante :
je suis le processus 2
je suis le processus 1
je suis le processus 2
je suis le processus 1
sem_t s1,s2 1pts
sem_init(s1,0,1) ; /*pour permettre au processus P2 de commencer*/ 0.5pt
sem_init(s2,0,0) /*pour empêcher le processus P1 de commencer jusqu’à ce que P2 le réveil */ 0.5pt
P1 ( ) { P2 ( ) {
while(TRUE) { while(TRUE) {
sim_wait(&s2) ; // 0,5 pt sim_wait(&s1) 0,5
printf("je suis le processus 1\n"); printf("je suis le processus 2\n");
sim_post(&s1) ; 0,5 sim_post(&s2); 0,5
} }
} }

1- Synchroniser les deux processus à l'aide des sémaphores afin de montrer à l'écran la sortie suivante:
je suis le processus 2
je suis le processus 1
je suis le processus 1
je suis le processus 2
sem_t s1, s2
sem_init(s1,0,2) ; /*pour permettre au processus P2 de commencer*/ 0.5pt
sem_init(s2,0,0) /*pour empêcher le processus P1 de commencer jusqu’à ce que P2 le réveil */ 0.5pt
P1( ) { P2 ( ) {
While (TRUE){ While (TRUE){
sim_wait(&s2) ; // (0,5 pt) sim_wait(&s1) ;sim_wait(&s1); (1 pt)
printf("je suis le processus 2\n"); ; printf("je suis le processus 2\n"); ;
sim_post(&s1) ; // (0,5 pt) sim_post(&s2); sim_post(&s2) ; (1 pt)
} }
} }
Exercice 3 (5 pts) ::
Écrire un programme utilisant 3 threads afin d'afficher la séquence suivante:
A, B,C, A,B, C...,
Où, le thread 1 affiche la lettre A, le thread 2 affiche la lettre B et le thread 3 affiche la lettre C

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t sem1, sem2, sem3;
void *f1(){ void *f2(){ void *f3(){
while(1){ while(1) { while(1) {
sem_wait(&sem1); sem_wait(&sem2); sem_wait(&sem3);
printf("A, "); printf("B, "); printf("C, ");
sem_post(&sem2); sem_post(&sem3); sem_post(&sem1);
} } }
} } }

int main(){
pthread_t p1, p2, p3;
sem_init(&sem1, 0, 1);
sem_init(&sem2, 0, 0);
sem_init(&sem3, 0, 0);
pthread_create(&p1, NULL, f1, (void*)NULL);
pthread_create(&p2, NULL, f2, (void*)NULL);
pthread_create(&p3, NULL, f3, (void*)NULL);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
pthread_join(p3, NULL);
return 0;
}

Exercice4 (5 pts) :
Écrire un programme en C qui :
 Initialise un tableau aléatoirement,
 Crée un processus fils,
 Calcule la somme des éléments du tableau dans une variable S,
 Attend la terminaison de son fils et affiche S.
Le processus fils calcule et affiche le maximum du tableau.

# define N 100
int main () { if (P == 0) { else {
float t[N], S=0,max=0; for(i=0 ; i<N ; i++) for(i=1; i<N; i++)
int i; if (max < t[i]) S+= t[i];
pid_t P max= t[i]; waitpid (P ,NULL ,0);
for (i=0; i < N; i++) printf ("Max=%f \n", max); printf ("S=%f \n", S);
t[i] = rand (); } }
P = fork (); return 0;
}

A. ABBAS 2
Département d’informatique, Université de Bouira
L3 SI (2023/2024) Durée : 1h30
ExamEn : SyStèmE d’Exploitation 2

Exercice 1 (3 pts) :
1. Dans quel(s) état(s) peut se retrouver un processus juste après son exécution ?
prêt, bloqué ou terminer
2. Citez quatre (4) mécanismes qui permettent de contrôler les accès aux données partagées.
Les mécanismes sont : mécanisme d'attente active, peterson, les sémaphores et
moniteur.

Exercice 2 (3 pts): On considère deux processus P1 et P2 concurrents. Les codes des


processus P1 et P2 sont les suivants:
P1 ( ) { P2 ( ) {
while(TRUE) { while(TRUE) {
Afficher ("1"); Afficher ("2");
Afficher ("3"); Afficher ("4");
} }
} }
Question:
Intégrer deux sémaphores S1 et S2 dans le code de ces processus afin d'afficher la séquence
suivante: 1,2,3,4, 1,2,3,4, 1,2,3,4 .....
S1=1,S2=0,
P1 ( ) { P2 ( ) {
while(TRUE) { while(TRUE) {
P(S1) P(S2)
Afficher ("1"); Afficher ("2");
V(S2) V(S1)
P(S1) P(S2)
Afficher ("3"); Afficher ("4");
V(S2) V(S1)
} }
} }
Exercice 3 (6 pts):
Considérons le pseudo-code du moniteur suivant:
monitor m() {
int x=10 ; y=2 ; condition c;
P1() { P2() {
(1) x++; (4) if (x>10)
(2) y = x-2; (5) x--
(3) [Link]; (6) else {[Link];
} (7) x++;}
}}
Supposons que, après l’initialisation du moniteur, les procédures P1 et P2 sont appelées dans l'ordre
suivant par divers processus: m.P2(); m.P1(); m.P2();

Question:
En utilisant les numéros de lignes dans le code, tracer la séquence d'exécution d'instruction, sous
forme du tableau donné ci-après. Montrer les valeurs de x et y à la fin de chaque instruction.
Appel de la procédure Numéro de lignes (i) Valeur de X Valeur de Y
du moniteur
... ... ... ...
Département d’informatique, Université de Bouira
L3 SI (2023/2024) Durée : 1h30
ExamEn : SyStèmE d’Exploitation 2

Appel de la procédure Numéro de lignes (i) Valeur de X Valeur de Y


du moniteur
P2(); 4 10 2
6 10 2
P1(); 1 11 2
2 11 9
3 11 9
7 12 9
P2(); 4 12 9
5 11 9
Exercice 4 (8 pts) :
Considérons un processus possédant N (20) threads. Chacun de ces threads travaille en deux étapes.
Durant la première étape, tous les threads sont indépendants, peuvent s'exécuter simultanément et
affichent leurs TID. Cependant, un thread ne peut démarrer sa deuxième étape que si seulement si
les autres threads ont terminé leur première étape.
Question :
Ecrire le programme en C de ce processus en utilisant les sémaphores. Le processus père doit
attendre la fin de l'exécution de tous les threads.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
sem_t rendezvous, S;
int count=0;
N=20;
void* F(void* arg){
//Etape 1
printf("Etape 1 Tache: %d\n", pthread_self());
sem_wait(&S);
count++;
if(count==N) {
sem_post(&rendezvous); // tous les threads sont arrivés
}
sem_post(&S);
sem_wait(&rendezvous);// attente à la barrière

sem_post(&rendezvous);// libération d'un autre thread en attente


//Etape 2
printf("Etape 2 Tache: %d\n", pthread_self());
pthread_exit(0);
}
int main(void){
sem_init(&S,0,1);
sem_init(&rendezvous,0,0);
pthread_t T[N];
for (int i=1;i<=N;i++)
pthread_create (&T[i], NULL, F, NULL);
for (int i=1;i<=N;i++)
pthread_join(T[i], NULL);
return 0;}
A. ABBAS 2 Bon
courage
Examen système d’exploitation Département d’informatique, Université de Bouira

1ère Année Master ISIL (2017/2018) Durée : 1h30 Documents non autorisés

Exercice 1 (3 pts) :
1. Qu’est-ce qu’un PCB et de quoi est-il composé ? (0,5 pt)

PCB est une structure de données particulière appelée bloc de contrôle de processus (PCB :
Process Control Bloc) et dont le rôle est de reconstituer le contexte du processus.

PCB est composé de l'ensemble des informations dynamiques qui représente l‘état d‘ exécution
d'un processus. Il contient aussi des informations sur l'ordonnancement du processus (priorité du
processus, les pointeurs sur les files d'attente)

2. L'appel système fork() est le moyen pour créer des processus, par duplication d'un processus
existant. Expliquer comment distinguer entre le processus père et le processus fils. (0,5 pt)
Pour distinguer le processus père du processus fils on regarde la valeur de retour de fork(), qui peut
être:
 La valeur 0 dans le processus fils.
 Positive pour le processus père et qui correspond au PID du processus fils.
 Négative si la création de processus fils a échoué ;
3. Quelles critiques peut-on faire aux solutions de l'attente active et Peterson du problème de
l'exclusion mutuelle ?

Attente active : (1 pt)


1- Cette méthode n'assure pas l'exclusion mutuelle
2- Susceptible de consommer du temps en bouclant inutilement.
Peterson : (1 pt)
1- La généralisation de cette solution aux cas de plusieurs processus est bien complexe.
2- Susceptible de consommer du temps en bouclant inutilement.
Exercice 2 (6 pts) :
On cherche à évaluer l'expression suivante
e := ((b-d) * (a+c) + (e*f)) / (a+c)
1. Réaliser un découpage en tâches de cette expression sans l'ajout de variables intermédiaires.
(2 pts)
t1: b = b - d
t2: a = a + c
t3: e = e * f
t4: b = b * a
t5: b = b + e
t6: e = b / a
2. En vous servant de la définition de la condition de Bernstein, donner le graphe de précédence
correspondant.
t1: {R(t1) = d, W(t1) = b};
Examen système d’exploitation Département d’informatique, Université de Bouira

t2: {R(t2) = c, W(t2) = a};


t3: {R(t3) = f, W(t3) = e}
t4: {R(t4) = a, W(t4) = b};
t5: {R(t5) = e, W(t5) = b};
t6: {R(t6) = b, a, W(t6) = e}

On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites : (2pts)
a) R (ti) ∩ W (tj) =∅
b) W (ti) ∩ R (tj) =∅ t2 t1 t3
c) W(ti) ∩ W (tj) =∅

Le graphe est le suivant t4

t5
t6

En se basant sur le graphe obtenu, réaliser la synchronisation des tâches (processus) en utilisant trois (03)
sémaphores S1, S2 et S3. (2pts)
Sémaphore S1=0, S2=0, S3=0

Pt1 (){ Pt2 (){ Pt3 (){ Pt4 (){ Pt5 (){ Pt6 (){
t1: b = b - d; t2: a = a + c; t3: e = e * f; P(S1); P(S1); P(S2);P(S2); P(S3);P(S3);
V(S1); V(S1); V(S3); V(S2); t4: b = b * a t5: b = b + e; t6: e = b / a;
} } } V(S2) V(S3) }
} }

Exercice 3 (7 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du buffer et le place dans la ZoneC où il
peut le consommer. Ce problème induit plusieurs types de contraintes de synchronisation qui sont:
1. Un producteur ne doit pas produire, ni déposer le message dans le buffer quand il n y a plus de
place pour déposer ce qu’il a produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
- Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.
Semaphore Mutex = 1, Plein = 0, Vide=n ; Message tampon[];
Producteur (){ Consommateur (){
Message m ; Message m ;
Tantque Vrai faire Tantque vrai faire
P(Vide); P(Plein);
m = creermessage() ; P(Mutex);
P(Mutex) ; m = LectureTampon();
EcritureTampon(m); V(Mutex);
V(Mutex) ; V(Vide);
V(Plein); Fin Tantque
FinTantque }
}
Exercice 4 (4 pts) : Soit le programme ci-dessous :

# define N 100 for (i=0;i<N;i++) else {


int k = 0; t[i] = rand (); for(i=1;i<N;i++)
int main () { P = fork (); t [0]+= t[i];
float t[N]; if (P ==0) { waitpid (P ,NULL ,0);
int i; k=1; }
pid_t P for(i=0 ; i<N ; i++) printf ("processus%d, %f \n",k, t[0]);
if (t[0] < t[i]) return 0;
t[0]= t[i]; }
}

1- Que fait le "processus 0" et le "processus 1" dans le code ci-dessus? Expliquez. (3pts)
1- Le processus 0 (le père) initialise un tableau aléatoirement, exécute l'appel système fork, calcule la
somme des éléments du tableau dans t[0], attend la terminaison de son fils et affiche t[0].
Le processus 1 (le fils) calcule le maximum du tableau dans t[0] qui il affiche.
2- Y a-t-il un risque pour que les deux processus fournissent des résultats incohérents ? Expliquez. (1pt)
Remarque : les processus s’annoncent à la fin du code avant le return 0

2 Non, car les deux processus ont des espace de données différents (pas de variable partagée)

A. ABBAS 3 Bon courage


Département d’informatique, Université de Bouira
Examen système d’exploitation L3-SI Durée : 1h00
Exercice 1 (4 pts) :
1. Quelles sont les inconvénients des solutions de l'attente active et Peterson du problème de
l'exclusion mutuelle ?
2. Attente active : (2 pt)
3. 1- Cette méthode n'assure pas l'exclusion mutuelle
4. 2- Susceptible de consommer du temps en bouclant inutilement.
5. Peterson : (2 pt)
6. 1- La généralisation de cette solution aux cas de plusieurs processus est bien complexe.
7. 2- Susceptible de consommer du temps en bouclant inutilement.
Exercice 2 (5 pts) :
On cherche à évaluer l'expression suivante
e := ((b - d) * (a+ c) + (e*f)) / (a+c)
1. Réalise un découpage en tâches de cette expression sans l'ajout de variables intermédiaires. 1pt
t1: b = b - d
t2: a = a + c
t3: e = e * f
t4: b = b * a
t5: b = b + e
t6: e = b / a
2. En vous servant de la définition de la condition de Bernstein, donner le graphe de précédence
correspondant. 2 pt
t1: R(t1) = {d}, W(t1) ={ b};
t2: R(t2) ={ c}, W(t2) = {a};
t3: R(t3) = { f}, W(t3) ={ e}
t4: R(t4) ={ a}, W(t4) = {b};
t5: R(t5) ={e}, W(t5) = {b};
t6: R(t6) ={b, a}, W(t6) = {e}

On dira que deux tâches (instructions) ti et tj peuvent s’exécuter en parallèle si les conditions
suivantes sont satisfaites :
a) R (ti) ∩ W (tj) =∅
b) W (ti) ∩ R (tj) =∅
c) W(ti) ∩ W (tj) =∅
t1 // t2
t1 // t3
t1 → t4 : t1 précéde t4 puisque le b de t4 est celui calculé par t1
t1 t5 : t1 ne précéde pas t5 puisque le b de t5 (W(t1) ∩ W (t5)= {b}) ce n'est pas celui calculé par t1
mais c'est celui de t4
t1 t6 : même chose t2 t1 t3
t2 // t3
t2 → t4
t2 // t5 t4 t4 → t5
t2→ t6 t4 t6
t3 // t4 t5
t3 → t5 t5 → t6
t3 t6 t6

Dr. A. ABBAS 1
Département d’informatique, Université de Bouira
Examen système d’exploitation L3-SI Durée : 1h00
3. En se basant sur le graphe obtenu, réaliser la synchronisation des tâches (processus) en utilisant trois (03)
sémaphores S1, S2 et S3. 2pts
Sémaphore S1=0, S2=0, S3=0
Pt1 (){ Pt2 (){ Pt3 (){ Pt4 (){ Pt5 (){ Pt6 (){
t1: b = b - d; t2: a = a + c; t3: e = e * f; P(S1); P(S1); P(S2);P(S2); P(S3);P(S3);
V(S1); V(S1); V(S3); V(S2); t4: b = b * a t5: b = b + e; t6: e = b / a;
} } } V(S2) V(S3)
} }

Exercice 3 (6 pts) :
Soit une route reliant la ville A et la ville B. Les règles de circulation sur cette route sont les suivantes:
1. Des voitures peuvent y circuler ensemble dans le sens A → B ou dans le sens B → A
(circulation alternée),
2. La route ne doit jamais être empruntée simultanément par deux voitures allant en sens inverse.
3. La priorité d'accès à la route est la même pour les deux sens.
On considère donc deux classes d’utilisateurs (processus) : voitures de A vers B (V_AB) et voitures de
B vers A (V_BA).
Question:
En utilisant les sémaphores, écrivez les algorithmes des fonctions de demande d’accès aux tronçons
acces_AB(), acces_BA() et des fonctions de sortie des tronçons AB_sort () et BA_sort() de façon à ce
que les processus V-AB et V-BA respectent les trois règles de circulation sur la route. Précisez
clairement vos déclarations et initialisations.
Solution:
Initialisation 2pts
int nbAB=0; //Compte le nombre de voitures allant de A vers B
int nbBA =0; entier (init à 0) Compte le nombre de voitures allant de B vers A
Sempahore route=1; // pour permettre que des voitures de sens contraire ne s'engagent pas dans la voie en
même temps.
Sempahore mutexAB=1;//pour protéger la mise à jour en exclusion mutuelle de la variable protégée nbAB
Sempahore mutexBA=1; //pour protéger la mise à jour en exclusion mutuelle de la variable protégée nbBA
Code des fonctions 1pt/fonction
Fonction acces_AB() { Fonction acces_BA () {
P(mutexAB); P(mutexBA);
nbAB++; nbAB++;
si (nbAB == 1) P(route); si (nbAB == 1) P(route);
V(mutexAB);} V(mutexBA);}
Fonction AB_sort () Fonction BA_sort () {
P(mutexAB); (mutexBA);
nbAB--; nbBA--;
si (nbAB == 0) V(route); si (nbBA == 0) V(route);
P(mutexAB);} (mutexBA);}
Exercice 4 (5 pts) :
Écrire un programme qui crée 5 processus fils, chaque fils affiche son PID et se termine. Le père devra
attendre la fin de ses 5 fils et afficher quel a été le premier et dernier processus qui a terminé.

#include <stdio.h>
#include <stdlib.h>

Dr. A. ABBAS 2
Examen système d’exploitation Département d’informatique, Université de Bouira

#include <sys/types.h>
#include <unistd.h>
int main(){
pid_t pid_premier, pid_dernier;
int i,pid[5],status;
for(i=0;i<5;i++){
pid[i]=fork();
if (pid[i] == -1) {
// ERREUR
fprintf(stderr, "Impossible de créer un fils (%d)\n", i);
} else if (pid[i]==0) {
// FILS
printf("Fils %2d (PID=%d): Activé\n", i, getpid());
exit(0);
} else {
printf("Père : Activation du fils %2d\n", i);
}
}
pid_premier = wait(&status);
wait(&status);
wait(&status);
wait(&status);
pid_dernier = wait(&status);
printf("Premier processus a finir : %d\n", pid_premier);
printf("Dernier processus a finir : %d\n", pid_dernier);
return 0;
}

A. ABBAS 3 Bon courage


Université de Bouira
Département d’informatique 3ième Année SI (2020/2021)
Module : système d'exploitation Durée : 1h
Examen Système d'exploitation
Exercice 1 (5 pts) :
1. Quelle est la différence entre un processus lourd et un processus léger (thread) ? (4pts)
Le processus lourd est créé par duplication (copie exacte du processus original) d'un processus existant.
Le deux processus lourd ne partage pas le même espace mémoire.
2. Dans quel(s) état(s) peut se retrouver un processus après l'état Prêt? (1 pt)
Après l'état Prêt, un processus peut se trouver dans l'état exécution
Le thread créateur et le thread créé partagent tous deux le même espace mémoire

Exercice 2 (8 pts) : Soit le programme suivant de synchronisation de deux threads avec l'utilisation de
sémaphores.
#include <stdio.h> void *thread2 (void * arg){
#include <stdlib.h> while(1) {
#include <pthread.h> sem_wait(&my_sem2); //(0.5 pt)
#include <semaphore.h> printf ("Je suis thread2,");
sem_t *my_sem1, *my_sem2; //(1 pt) sem_post(&my_sem1); //(0.5 pt)
}}

void *thread1 (void * arg) { void main (int ac, char **av){
while(1) { pthread_t *th1, *th2;
sem_wait(&my_sem1); // (0.5 pt) sem_init(&my_sem1, 0 ,1); //(0.5 pt)
printf ("Je suis thread1,"); sem_init(&my_sem2, 0 ,0); //(0.5 pt)
sem_post(&my_sem2); //(0.5 pt) pthread_create(&th1, NULL,&thread1, NULL) ;
} } pthread_create(&th2, NULL,&thread2, NULL) ;
pthread_join(th1, NULL);
pthread_join(th2, NULL);
printf ("Je suis main,");
}
Question :
1. Complétez ce programme pour qu'il affiche la séquence suivante : Je suis thread1, Je suis thread2,
Je suis thread1, Je suis thread2,....
2. Utiliser le programme précédent pour écrire un autre programme qui initialise une variable entière
cpt à 1 et qui crée deux threads p1 et p2. Le thread p1 incrémente cpt 10000 fois et le thread p2
décrémente cpt 10000 fois. Utiliser un sémaphore pour résoudre le problème de l’accès concurrent à
la variable cpt.
#include <stdio.h> void* p2(void* arg){
#include <stdlib.h> int i=0;
#include <unistd.h> while (i<10000){
#include <pthread.h> sem_wait(&semaphore); (0.5 pt)
#include <semaphore.h> cpt -=1;
sem_t semaphore; (1 pt) sem_post(&semaphore); (0.5 pt)
int cpt =1; i++;
}
void* p1(void* arg){ }
int i=0; int main(void) {
while (i<10000){ pthread_t tache1, tache2;
sem_wait(&semaphore); (0.5 pt) sem_init(&semaphore, 0, 1); (1 pt)
cpt +=1; pthread_create (&tache1, NULL, &p1, NULL);
sem_post(&semaphore); (0.5 pt) pthread_create (&tache2, NULL, &p2, NULL);
i++; pthread_join(tache1, NULL);
} pthread_join(tache2, NULL);
} printf("cpt =%d:\n", cpt );
return 0;
}
Université de Bouira
Département d’informatique 3ième Année SI (2020/2021)
Module : système d'exploitation Durée : 1h
Examen Système d'exploitation

Exercice 3 (7 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du Buffer et le place dans la ZoneC où il
peut le consommer. Ce problème introduit plusieurs types de contraintes de synchronisation:
1. Un producteur ne doit pas déposer dans le buffer quand il n y a plus de place pour déposer ce qu’il a
produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
Question :
Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.
Semaphore Mutex = 1, Plein = 0, Vide=n ; (2 pt)
Message tampon[];
Producteur ( ){ Consommateur( ) {
Message m ; Message m ;
Tantque Vrai faire Tantque Vrai faire
P(Vide); (1 pt) P(Plein); (1 pt)
m = creermessage() ; P(Mutex) ; (0.5 pt)
P(Mutex) ; (0.5 pt) m = LectureTampon();
EcritureTampon(m); V(Mutex) ; (0.5 pt)
V(Mutex) ; (0.5 pt) V(Vide); (1 pt)
V(Plein); (1 pt) Fin Tantque
FinTantque } }

Exo1: Soit le graphe de précédence des processus {A, B, C, D, et E} (12 pts)

A. ABBAS 2 Bon courage


Examen système d'exploitation Département d’informatique, Université de Bouira

Test

C D
A
B

E
- Réaliser la synchronisation de ces processus en utilisant les sémaphores.
Sémaphore S1=0, S2=0;S3=0

PA (){ PB (){ PC (){ PD (){ PE (){


I; P(S1) P(S1) P(S2); P(S3)
V(S1); I; I; P(S2); P(S3)
V(S1); V(S2); V(S2); I; P(S3)
V(S3); V(S3); } V(S3); I;
} } } }

Exo1: Expliquez pas-à-pas comment s'exécute le programme suivant et donner le résultat d'affichage. (8 pts)
1. main () {
2. int y ;
3. y=0 ;
4. pid_t thr ;
5. thr =fork() ;
6. if (thr ==0) {
7. y=5 ;
8. prinf(‘‘y=%d\n’’, y) ;
9. } else
10. prinf(‘‘y=%d\n’’, y) ;
11. }
inst2et3: déclaration d'une varaible y de type int et affectation de 0
inst4: déclaration d'une varaible thr de type pid_t
inst5: création du processus fils suite à l'appel de la fonction fork() et affectation de la
valeur de retour à la variable thr
inst6: test la valeur de thr, si elle égale à 0 alors on est dans le fils
inst7: le processus fils affecte 5 à y
inst8: le processus fils affiche: y=5
inst9: si la valeur de thr différente de 0 alors on est dans le père
inst10: le processus père affiche: y=0

A. ABBAS 3 Bon
courage
Université de Bouira
Département d’informatique 3ième Année SI (2020/2021)
Module : système d'exploitation Durée : 1h

Rattrapage Système d'exploitation


Exercice 1 (5 pts) :

1. Quelle est la différence entre un processus lourd et un processus léger (thread) ?


2. Dans quel(s) état(s) peut se retrouver un processus après l'état Prêt?

Exercice 2 (8 pts) : Soit le programme suivant de synchronisation de deux threads avec l'utilisation de
sémaphores.
#include <stdio.h> void *thread2 (void * arg){
#include <stdlib.h> while (1) {
#include <pthread.h>
#include <semaphore.h> printf ("Je suis thread2,");

............................. my_sem; }
}
void *thread1 (void * arg) { void main (int ac, char **av){
while (1) { pthread_t th1, th2;
sem_init (&my_sem, ...... , ......);
printf ("Je suis thread1,"); pthread_create (..............., NULL, ........., NULL) ;
pthread_create (................, NULL, ........., NULL) ;
} pthread_join (................, NULL);
} pthread_join (................, NULL);
}

Question :
1. Complétez ce programme pour qu'il affiche la séquence suivante : Je suis thread1, Je suis thread2,
Je suis thread1, Je suis thread2,....
2. Utiliser le programme précédent pour écrire un autre programme qui initialise une variable entière
cpt à 1 et qui crée deux threads p1 et p2. Le thread p1 incrémente cpt 10000 fois et le thread p2
décrémente cpt 10000 fois. Utiliser un sémaphore pour résoudre le problème de l’accès concurrent à
la variable cpt.

Exercice 3 (7 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du Buffer et le place dans la ZoneC où il
peut le consommer. Ce problème introduit plusieurs types de contraintes de synchronisation:
1. Un producteur ne doit pas déposer dans le buffer quand il n y a plus de place pour déposer ce qu’il a
produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
Question :
Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.

A. ABBAS 1 Bon courage


Université de Bouira
Département d’informatique 3ième Année ISIL (2020/2021)
Module : système d'exploitation Durée : 30mn
Test
Exo1: Soit le graphe de précédence des processus {A, B, C, D, et E} (12 pts)

C D
A
B

E
- Réaliser la synchronisation de ces processus en utilisant les sémaphores.

Exo1: Expliquez pas-à-pas comment s'exécute le programme suivant et donner le résultat d'affichage. (8 pts)
1. main () {
2. int y ;
3. y=0 ;
4. pid_t thr ;
5. thr =fork() ;
6. if (thr ==0) {
7. y=5 ;
8. prinf(‘‘y=%d\n’’, y) ;
9. } else
10. prinf(‘‘y=%d\n’’, y) ;
11. }

A. ABBAS 2 Bon courage


Examen système d’exploitation Département d’informatique, Université de Bouira

3ème Année Licence SI (2021/2022) Durée : 1h30

Exercice 1 (4 pts) :

1. Que font les fonctions : pthread_self() , pthread_join() ; fork() ?


0.5 pthread_self():Retourne le TID du thread.
0.5 pthread_join(): Le Processus exécutant cette fonction attend la fin de l'exécution du thread passé
en arguments, pour continuer sa propre exécution.
1 fork():est un moyen offre par SE afin de créer des processus, par duplication d'un processus
existant.
2. Quelle est la différence entre section critique et ressource critique ?
1 Une section critique (SC): est un ensemble d'instruction d'un programme qui peuvent engendrer
des résultats imprévisibles (ou incohérents) lorsqu'elles sont exécutées simultanément par des
processus différents. Une SC est une suite d'instructions qui opèrent sur une ou plusieurs ressources
partagées (critiques) et qui nécessitent une utilisation exclusive de ces ressources.
1 On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès concurrent
(ou simultané) par plusieurs processus.

Exercice 2 (6 pts) :

Soit le schéma suivant décrivant les transitions d’un processus. Précisez dans le tableau ci-dessous à quoi
correspondent les transitions numérotées par 1, 2, 3, 4 et précisez quels sont les événements qui
provoquent chacune de ces transitions.

Nouveau Fin

1
Prêt En exécution
2

4 3
Bloqué

N° transition Transition 0.5 Événements 1/évenement


1 Élection Le processus obtient l'affectation du processeur
2 Interruption Fin de quantum ou arrivée d'un processus plus prioritaires
3 Attente Attente E/S ou attente d'un événement
4 Fin d'attente Fin E/S ou arrivée d'un événement.

Exercice 3 (5 pts):
Considérons un objet (une base de données par exemple) qui n'est accessible que par deux catégories
d'opérations : les lectures et les écritures. Plusieurs lectures (consultations) peuvent avoir lieu
simultanément ; par contre les écritures (mises à jour) doivent se faire en exclusion mutuelle. Ce
problème induit plusieurs types de contraintes de synchronisation qui sont:
• Si un lecteur demande à lire et qu'il y a une écriture en cours, la demande est mise en attente. De
même que si un rédacteur demande à écrire et qu'il y a au moins une lecture en cours, la demande
est mise en attente.

Dr. A. ABBAS 1
Examen système d’exploitation Département d’informatique, Université de Bouira

• Si un rédacteur demande à écrire et qu'il y a une écriture en cours, la demande est mise en attente.
Question :
- Écrire l'algorithme des processus lectures et rédacteur en utilisant les sémaphores.

Exercice 4 (5 pts) :
En se basant sur les sémaphores, écrire un programme utilisant 3 threads afin d'afficher la séquence
suivante: A, B, C, A, B, C...,
Où, le thread T1 affiche: A, le thread T2 affiche: B, et le thread T3 affiche: C,

#include <stdio.h> void *CT3 (void * arg){ 1


#include <stdlib.h> while (1) {
#include <pthread.h> sem_wait(&my_sem3);
#include <semaphore.h> printf ("C,");
sem_post(&my_sem1);
sem_t my_sem1,my_sem2,my_sem3; 0.5
}
void *T1 (void * arg){ 1 }
while (1) { void main (int ac, char **av){
sem_wait(&my_sem1); pthread_t th1, th2,th3;
printf ("A,"); sem_init (&my_sem1, 0, 1); .5
sem_post(&my_sem2); sem_init (&my_sem2, 0, 0); .5
} sem_init (&my_sem3, 0, 0); 0.5
} pthread_create (&th1, NULL, &T1, NULL) ;
void *T2 (void * arg){ 1 pthread_create (&th2, NULL, &T2, NULL) ;
pthread_create (&th3, NULL, &T3, NULL) ;
while (1) { pthread_join (th1, NULL);
sem_wait(&my_sem2); pthread_join (th2, NULL);
printf ("B,"); pthread_join (th3, NULL);
sem_post(&my_sem3); }

}
}

Dr. A. ABBAS 2
Département d’informatique, Université de Bouira
Module : Système d'exploitation M1-ISIL (2021)

Examen de remplacement

Exercice 1 (4 pts) :

1. Pour exécuter en parallèle plusieurs instructions d'une même application, vous avez le choix
d’utiliser les appels système pthread_create() et fork(). Laquelle des deux possibilités à choisir ?
Pourquoi ?
- On choisi pthread _create ( ) car le fork( ) consomme beaucoup d’espace (duplication de
processus). Mais il faut faire attention au conflit d’accès aux objets partagés. (2 pts)

2. Que fait la fonction pthread_join ?


Le Processus exécutant cette fonction (dans ce cas main) attend la fin de l'exécution du thread
passé en arguments, pour continuer sa propre exécution.

Exercice 2 (6 pts) :

Soit le schéma suivant décrivant les transitions d’un processus. Précisez dans le tableau ci-
dessous à quoi correspondent les transitions numérotées par 1, 2, 3, 4 et précisez quels sont
les événements qui provoquent chacune de ces transitions.

Nouveau Fin

1
Prêt En exécution
2

4 3
Bloqué

N° transition Transition Événements


1 Élection Le processus obtient l'affectation du processeur
2 Interruption Fin de quantum ou arrivée d'un processus plus prioritaires
3 Attente Attente E/S ou attente d'un événement
4 Fin d'attente Fin E/S ou arrivée d'un événement.

Exercice 3 (5 pts) :
En se basant sur les sémaphore, écrire un programme utilisant 3 threads (A, B et C) afin
d'afficher la séquence suivante: 1,2,3,1,2,3, 1,2,3, ....., où le thread A affiche le chiffre 1, le
thread B affiche le chiffre 2 et le thread C affiche le chiffre 3.

solution:

Dr. A. ABBAS 1
Département d’informatique, Université de Bouira
Module : Système d'exploitation M1-ISIL (2021)

#include <stdio.h>
#include <stdlib.h> void *C (void * arg){
#include <pthread.h> while (1) {
#include <semaphore.h> sem_wait(&my_sem3);
sem_t my_sem1,my_sem2,my_sem3; printf ("3,");
void *A (void * arg){ sem_post(&my_sem1);
while (1) {
sem_wait(&my_sem1); }
printf ("1,"); }
sem_post(&my_sem2); void main (int ac, char **av){
} pthread_t th1, th2,th3;
} sem_init (&my_sem1, 0, 1);
void *B (void * arg){ sem_init (&my_sem2, 0, 0);
sem_init (&my_sem3, 0, 0);
while (1) { pthread_create (&th1, NULL, &A, NULL) ;
sem_wait(&my_sem2); pthread_create (&th2, NULL, &B, NULL) ;
printf ("2,"); pthread_create (&th3, NULL, &C, NULL) ;
sem_post(&my_sem3); pthread_join (th1, NULL);
pthread_join (th2, NULL);
} pthread_join (th3, NULL);
} }
Exercice 4 (5 pts) :
Considérons un objet (une base de données par exemple) qui n'est accessible que par deux
catégories d'opérations : les lectures et les écritures. Plusieurs lectures (consultations)
peuvent avoir lieu simultanément ; par contre les écritures (mises à jour) doivent se faire en
exclusion mutuelle. Ce problème induit plusieurs types de contraintes de synchronisation
qui sont:
• Si un lecteur demande à lire et qu'il y a une écriture en cours, la demande est mise
en attente. De même que si un rédacteur demande à écrire et qu'il y a au moins une
lecture en cours, la demande est mise en attente.
• Si un rédacteur demande à écrire et qu'il y a une écriture en cours, la demande est
mise en attente.
Question :
- Écrire l'algorithme des processus lectures et rédacteur en utilisant les sémaphores.

Dr. A. ABBAS 2
Département d’informatique, Université de Bouira
Module : Système d'exploitation M1-ISIL (2021)

Test de remplacement
Exercice 1: 6 pts
Expliquer pour quoi le partage des ressources sans précaution particulière peut conduire à des
résultats imprévisibles.
Solution
La mise à jour concurrente peut générer des incohérences, où les ressources partagée, auront
des valeurs finales déférentes après l'exécution du même code. La cause de ces incohérences
est due à l'utilisation simultanée de la ressource partagée par plusieurs processus ou threads.
Pour expliquer ce fait, on donne l'exemple suivant:

20000

Exercice 2: 14 pts
En se basant sur le programme de l'exercice 3 de l'examen, écrire un autre programme
utilisant 3 threads (A, B et C) afin d'afficher la séquence suivante: 1,1,1, 2,3, 1,1,1, 2,3,
1,1,1, 2,3, ....., où le thread A affiche le chiffre 1, le thread B affiche le chiffre 2 et le thread C
affiche le chiffre 3.

#include <stdio.h> }
#include <stdlib.h>
#include <pthread.h> void *B (void * arg){
#include <semaphore.h>
while (1) {
sem_t my_sem1,my_sem2,my_sem3; sem_wait(&my_sem2);
sem_wait(&my_sem2);
void *A (void * arg){ sem_wait(&my_sem2);
printf ("2,");
while (1) { sem_post(&my_sem3);
sem_wait(&my_sem1);
printf ("1,"); }
sem_post(&my_sem2); }
}

Dr. A. ABBAS 3
Département d’informatique, Université de Bouira
Module : Système d'exploitation M1-ISIL (2021)

void *C (void * arg){


while (1) {
sem_wait(&my_sem3);
printf ("3,");
sem_post(&my_sem1);
sem_post(&my_sem1);
sem_post(&my_sem1);

}
}

void main (int ac, char **av){


pthread_t th1, th2,th3;
sem_init (&my_sem1, 0, 3);
sem_init (&my_sem2, 0, 0);
sem_init (&my_sem3, 0, 0);
pthread_create (&th1, NULL, &A, NULL) ;
pthread_create (&th2, NULL, &B, NULL) ;
pthread_create (&th3, NULL, &C, NULL) ;
pthread_join (th1, NULL);
pthread_join (th2, NULL);
pthread_join (th3, NULL);
}

Dr. A. ABBAS 4
Examen système d’exploitation Département d’informatique, Université de Bouira

3ème Année Licence SI (2021/2022) Durée : 1h30

Exercice 1 (4 pts) :

1. Que font les fonctions : pthread_self() , pthread_join() ; fork() ?


0.5 pthread_self():Retourne le TID du thread.
0.5 pthread_join(): Le Processus exécutant cette fonction attend la fin de l'exécution du thread passé
en arguments, pour continuer sa propre exécution.
1 fork():est un moyen offre par SE afin de créer des processus, par duplication d'un processus
existant.
2. Quelle est la différence entre section critique et ressource critique ?
1 Une section critique (SC): est un ensemble d'instruction d'un programme qui peuvent engendrer
des résultats imprévisibles (ou incohérents) lorsqu'elles sont exécutées simultanément par des
processus différents. Une SC est une suite d'instructions qui opèrent sur une ou plusieurs ressources
partagées (critiques) et qui nécessitent une utilisation exclusive de ces ressources.
1 On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès concurrent
(ou simultané) par plusieurs processus.

Exercice 2 (6 pts) :

Soit le schéma suivant décrivant les transitions d’un processus. Précisez dans le tableau ci-dessous à quoi
correspondent les transitions numérotées par 1, 2, 3, 4 et précisez quels sont les événements qui
provoquent chacune de ces transitions.

Nouveau Fin

1
Prêt En exécution
2

4 3
Bloqué

N° transition Transition 0.5 Événements 1/évenement


1 Élection Le processus obtient l'affectation du processeur
2 Interruption Fin de quantum ou arrivée d'un processus plus prioritaires
3 Attente Attente E/S ou attente d'un événement
4 Fin d'attente Fin E/S ou arrivée d'un événement.

Exercice 3 (5 pts):
Considérons un objet (une base de données par exemple) qui n'est accessible que par deux catégories
d'opérations : les lectures et les écritures. Plusieurs lectures (consultations) peuvent avoir lieu
simultanément ; par contre les écritures (mises à jour) doivent se faire en exclusion mutuelle. Ce
problème induit plusieurs types de contraintes de synchronisation qui sont:
• Si un lecteur demande à lire et qu'il y a une écriture en cours, la demande est mise en attente. De
même que si un rédacteur demande à écrire et qu'il y a au moins une lecture en cours, la demande
est mise en attente.

Dr. A. ABBAS 1
Examen système d’exploitation Département d’informatique, Université de Bouira

• Si un rédacteur demande à écrire et qu'il y a une écriture en cours, la demande est mise en attente.
Question :
- Écrire l'algorithme des processus lectures et rédacteur en utilisant les sémaphores.

Exercice 4 (5 pts) :
En se basant sur les sémaphores, écrire un programme utilisant 3 threads afin d'afficher la séquence
suivante: A, B, C, A, B, C...,
Où, le thread T1 affiche: A, le thread T2 affiche: B, et le thread T3 affiche: C,

#include <stdio.h> void *CT3 (void * arg){ 1


#include <stdlib.h> while (1) {
#include <pthread.h> sem_wait(&my_sem3);
#include <semaphore.h> printf ("C,");
sem_post(&my_sem1);
sem_t my_sem1,my_sem2,my_sem3; 0.5
}
void *T1 (void * arg){ 1 }
while (1) { void main (int ac, char **av){
sem_wait(&my_sem1); pthread_t th1, th2,th3;
printf ("A,"); sem_init (&my_sem1, 0, 1); .5
sem_post(&my_sem2); sem_init (&my_sem2, 0, 0); .5
} sem_init (&my_sem3, 0, 0); 0.5
} pthread_create (&th1, NULL, &T1, NULL) ;
void *T2 (void * arg){ 1 pthread_create (&th2, NULL, &T2, NULL) ;
pthread_create (&th3, NULL, &T3, NULL) ;
while (1) { pthread_join (th1, NULL);
sem_wait(&my_sem2); pthread_join (th2, NULL);
printf ("B,"); pthread_join (th3, NULL);
sem_post(&my_sem3); }

}
}

Dr. A. ABBAS 2
Université de Bouira
Département d’informatique 3ième Année SI (2020/2021)
Module : système d'exploitation Durée : 1h
Examen Système d'exploitation
Exercice 1 (5 pts) :
1. Quelle est la différence entre un processus lourd et un processus léger (thread) ? (4pts)
Le processus lourd est créé par duplication (copie exacte du processus original) d'un processus existant.
Le deux processus lourd ne partage pas le même espace mémoire.
Le thread créateur et le thread créé partagent tous deux le même espace mémoire

2. Dans quel(s) état(s) peut se retrouver un processus après l'état Prêt? (1 pt)
Après l'état Prêt, un processus peut se trouver dans l'état exécution

Exercice 2 (8 pts) : Soit le programme suivant de synchronisation de deux threads avec l'utilisation de
sémaphores.
#include <stdio.h> void *thread2 (void * arg){
#include <stdlib.h> while(1) {
#include <pthread.h> sem_wait(&my_sem2); //(0.5 pt)
#include <semaphore.h> printf ("Je suis thread2,");
sem_t *my_sem1, *my_sem2; //(1 pt) sem_post(&my_sem1); //(0.5 pt)
}}

void *thread1 (void * arg) { void main (int ac, char **av){
while(1) { pthread_t *th1, *th2;
sem_wait(&my_sem1); // (0.5 pt) sem_init(&my_sem1, 0 ,1); //(0.5 pt)
printf ("Je suis thread1,"); sem_init(&my_sem2, 0 ,0); //(0.5 pt)
sem_post(&my_sem2); //(0.5 pt) pthread_create(&th1, NULL,&thread1, NULL) ;
} } pthread_create(&th2, NULL,&thread2, NULL) ;
pthread_join(th1, NULL);
pthread_join(th2, NULL);
printf ("Je suis main,");
}
Question :
1. Complétez ce programme pour qu'il affiche la séquence suivante : Je suis thread1, Je suis thread2,
Je suis thread1, Je suis thread2,....
2. Utiliser le programme précédent pour écrire un autre programme qui initialise une variable entière
cpt à 1 et qui crée deux threads p1 et p2. Le thread p1 incrémente cpt 10000 fois et le thread p2
décrémente cpt 10000 fois. Utiliser un sémaphore pour résoudre le problème de l’accès concurrent à
la variable cpt.
#include <stdio.h>
#include <stdlib.h> void* p2(void* arg){
#include <unistd.h> int i=0;
#include <pthread.h> while (i<10000){
#include <semaphore.h> sem_wait(&semaphore); (0.5 pt)
sem_t semaphore; (1 pt) cpt -=1;
int cpt =1; sem_post(&semaphore); (0.5 pt)
i++;
void* p1(void* arg){ }
int i=0; }
while (i<10000){ int main(void) {
sem_wait(&semaphore); (0.5 pt) pthread_t tache1, tache2;
cpt +=1; sem_init(&semaphore, 0, 1); (1 pt)
sem_post(&semaphore); (0.5 pt) pthread_create (&tache1, NULL, &p1, NULL);
i++; pthread_create (&tache2, NULL, &p2, NULL);
} pthread_join(tache1, NULL);
} pthread_join(tache2, NULL);
printf("cpt =%d:\n", cpt );
return 0;
Université de Bouira
Département d’informatique 3ième Année SI (2020/2021)
Module : système d'exploitation Durée : 1h
Examen Système d'exploitation
}

Exercice 3 (7 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du Buffer et le place dans la ZoneC où il
peut le consommer. Ce problème introduit plusieurs types de contraintes de synchronisation:
1. Un producteur ne doit pas déposer dans le buffer quand il n y a plus de place pour déposer ce qu’il a
produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
Question :
Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.
Semaphore Mutex = 1, Plein = 0, Vide=n ; (2 pt)
Message tampon[];
Producteur ( ){ Consommateur( ) {
Message m ; Message m ;
Tantque Vrai faire Tantque Vrai faire
P(Vide); (1 pt) P(Plein); (1 pt)
m = creermessage() ; P(Mutex) ; (0.5 pt)
P(Mutex) ; (0.5 pt) m = LectureTampon();
EcritureTampon(m); V(Mutex) ; (0.5 pt)
V(Mutex) ; (0.5 pt) V(Vide); (1 pt)
V(Plein); (1 pt) Fin Tantque
FinTantque } }

A. ABBAS 2 Bon courage


Examen système d'exploitation Département d’informatique, Université de Bouira

Test
Exo1: Soit le graphe de précédence des processus {A, B, C, D, et E} (12 pts)

C D
A
B

E
- Réaliser la synchronisation de ces processus en utilisant les sémaphores.
Sémaphore S1=0, S2=0;S3=0

PA (){ PB (){ PC (){ PD (){ PE (){


I; P(S1) P(S1) P(S2); P(S3)
V(S1); I; I; P(S2); P(S3)
V(S1); V(S2); V(S2); I; P(S3)
V(S3); V(S3); } V(S3); I;
} } } }

Exo1: Expliquez pas-à-pas comment s'exécute le programme suivant et donner le résultat d'affichage. (8 pts)
1. main () {
2. int y ;
3. y=0 ;
4. pid_t thr ;
5. thr =fork() ;
6. if (thr ==0) {
7. y=5 ;
8. prinf(‘‘y=%d\n’’, y) ;
9. } else
10. prinf(‘‘y=%d\n’’, y) ;
11. }
inst2et3: déclaration d'une varaible y de type int et affectation de 0
inst4: déclaration d'une varaible thr de type pid_t
inst5: création du processus fils suite à l'appel de la fonction fork() et affectation de la
valeur de retour à la variable thr
inst6: test la valeur de thr, si elle égale à 0 alors on est dans le fils
inst7: le processus fils affecte 5 à y
inst8: le processus fils affiche: y=5
inst9: si la valeur de thr différente de 0 alors on est dans le père
inst10: le processus père affiche: y=0

A. ABBAS 3 Bon
courage
Université de Bouira
Département d’informatique 3ième Année SI (2019/2020)
Module : système d'exploitation Durée : 1h
Examen de Rattrapage
Exercice 1 (4 pts) :
1. Qu’est-ce qu’un PCB et de quoi est-ce composé ? (1 pt)
PCB est une structure de données particulière appelée bloc de contrôle de processus (PCB : Process
Control Bloc) et dont le rôle est de reconstituer le contexte du processus.
PCB contient l'ensemble des informations dynamiques qui représente l‘état d‘ exécution d'un processus. Il
contient aussi des informations sur l'ordonnancement du processus (priorité du processus, les pointeurs
sur les files d'attente)
2. Dans quel(s) état(s) peut se retrouver un processus après l'état exécution? (1 pt)
Après l'état exécution, un processus peut se trouver dans l'une des états suivantes: Prêt, Bloqué ou Fin
3. Quelle est la différence entre un processus lourd et un processus léger (thread) ?
Le processus lourd est créé par duplication (copie exacte du processus original) d'un processus existant.
Le deux processus lourd ne partage pas le même espace mémoire. (1 pt)
Le thread créateur et le thread créé partagent tous deux le même espace mémoire (1 pt)
Exercice 2 (8 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du Buffer et le place dans la ZoneC où il
peut le consommer. Ce problème introduit plusieurs types de contraintes de synchronisation:
1. Un producteur ne doit pas déposer dans le buffer quand il n y a plus de place pour déposer ce qu’il a
produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
Question :
Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.
Semaphore Mutex = 1, Plein = 0, Vide=n ; (2 pt)
Message tampon[];
Producteur ( ){ Consommateur( ) {
Message m ; Message m ;
Tantque Vrai faire Tantque Vrai faire
P(Vide); (1 pt) P(Plein); (1 pt)
m = creermessage() ; P(Mutex) ; (0.5 pt)
P(Mutex) ; (0.5 pt) m = LectureTampon();
EcritureTampon(m); V(Mutex) ; (0.5 pt)
V(Mutex) ; (0.5 pt) V(Vide); (1 pt)
V(Plein); (1 pt) Fin Tantque
FinTantque } }
Exercice 3 (8 pts) : Soit le programme suivant de synchronisation de deux threads avec l'utilisation de
sémaphores.
#include <stdio.h> void *thread2 (void * arg){
#include <stdlib.h> while (1) {
#include <pthread.h> sem_wait(&my_sem2) (0.5 pt)
#include <semaphore.h> printf ("Je suis thread2,");
sem_t * my_sem1, * my_sem2; (1 pt) sem_post(&my_sem1) (0.5 pt)
void *thread1 (void * arg) { }}
while (1) { void main (int ac, char **av){
sem_wait(&my_sem1) (0.5 pt) pthread_t th1, th2;
printf ("Je suis thread1,"); sem_init (&my_sem1, 0 ,0); (0.5 pt)
sem_post(&my_sem2) (0.5 pt) sem_init (&my_sem2, 0 ,1); (0.5 pt)
} } pthread_create (&th1, NULL,&thread1, NULL) ;
pthread_create (&th2, NULL,&thread2, NULL) ;
pthread_join (&th1, NULL);
pthread_join (&th2, NULL);

A. ABBAS 1 Bon courage


Examen système d'exploitation Département d’informatique, Université de Bouira

Question :
1. Complétez ce programme pour qu'il affiche la séquence suivante : Je suis thread1, Je suis thread2,
Je suis thread1, Je suis thread2,....
2. Utiliser le programme précédent pour écrire un autre programme qui initialise une variable entière
cpt à 1 et qui crée deux threads p1 et p2. Le thread p1 incrémente cpt 10000 fois et le thread p2
décrémente cpt 10000 fois. Utiliser un sémaphore pour résoudre le problème de l’accès concurrent à
la variable cpt.
#include <stdio.h> void* p2(void* arg){
#include <stdlib.h> int i=0;
#include <unistd.h> while (i<10000){
#include <pthread.h> sem_wait(&semaphore); (0.5 pt)
#include <semaphore.h> cpt -=1;
sem_t semaphore; (0.5 pt) sem_post(&semaphore); (0.5 pt)
int cpt =1; (0.5 pt) i++;
void* p1(void* arg){ }
int i=0; }
while (i<10000){ int main(void) {
sem_wait(&semaphore); (0.5 pt) pthread_t tache1, tache2;
cpt +=1; sem_init(&semaphore, 0, 1); (0.5 pt)
sem_post(&semaphore); (0.5 pt) pthread_create (&tache1, NULL, &fonc1, NULL);
i++; pthread_create (&tache2, NULL, &fonc2, NULL);
} pthread_join(tache1, NULL);
} pthread_join(tache2, NULL);
printf("cpt =%d:\n", cpt ); (0.5 pt)
return 0;
}

A. ABBAS 2 Bon courage


Université de Bouira
Département d’informatique 3ième Année SI (2019/2020)
Module : système d'exploitation Durée : 1h
Examen de Rattrapage
Exercice 1 (4 pts) :
1. Qu’est-ce qu’un PCB et de quoi est-ce composé ? (1 pt)
PCB est une structure de données particulière appelée bloc de contrôle de processus (PCB : Process
Control Bloc) et dont le rôle est de reconstituer le contexte du processus.
PCB contient l'ensemble des informations dynamiques qui représente l‘état d‘ exécution d'un processus. Il
contient aussi des informations sur l'ordonnancement du processus (priorité du processus, les pointeurs
sur les files d'attente)
2. Dans quel(s) état(s) peut se retrouver un processus après l'état exécution? (1 pt)
Après l'état exécution, un processus peut se trouver dans l'une des états suivantes: Prêt, Bloqué ou Fin
3. Quelle est la différence entre un processus lourd et un processus léger (thread) ?
Le processus lourd est créé par duplication (copie exacte du processus original) d'un processus existant.
Le deux processus lourd ne partage pas le même espace mémoire. (1 pt)
Le thread créateur et le thread créé partagent tous deux le même espace mémoire (1 pt)
Exercice 2 (8 pts) :
On considère le problème du producteur consommateur. Le processus producteur, délivre des
messages à un processus consommateur. Le producteur produit le message dans la ZoneP, puis le
dépose dans le buffer. Le consommateur prélève un message du Buffer et le place dans la ZoneC où il
peut le consommer. Ce problème introduit plusieurs types de contraintes de synchronisation:
1. Un producteur ne doit pas déposer dans le buffer quand il n y a plus de place pour déposer ce qu’il a
produit.
2. Un consommateur ne doit pas prélever de messages quand le buffer est vide.
3. Producteurs et consommateurs ne doivent pas accéder en même temps au buffer.
Question :
Écrire l'algorithme des processus producteurs et consommateurs en utilisant les sémaphores.
Semaphore Mutex = 1, Plein = 0, Vide=n ; (2 pt)
Message tampon[];
Producteur ( ){ Consommateur( ) {
Message m ; Message m ;
Tantque Vrai faire Tantque Vrai faire
P(Vide); (1 pt) P(Plein); (1 pt)
m = creermessage() ; P(Mutex) ; (0.5 pt)
P(Mutex) ; (0.5 pt) m = LectureTampon();
EcritureTampon(m); V(Mutex) ; (0.5 pt)
V(Mutex) ; (0.5 pt) V(Vide); (1 pt)
V(Plein); (1 pt) Fin Tantque
FinTantque } }
Exercice 3 (8 pts) : Soit le programme suivant de synchronisation de deux threads avec l'utilisation de
sémaphores.
#include <stdio.h> void *thread2 (void * arg){
#include <stdlib.h> while (1) {
#include <pthread.h> sem_wait(&my_sem2) (0.5 pt)
#include <semaphore.h> printf ("Je suis thread2,");
sem_t * my_sem1, * my_sem2; (1 pt) sem_post(&my_sem1) (0.5 pt)
void *thread1 (void * arg) { }}
while (1) { void main (int ac, char **av){
sem_wait(&my_sem1) (0.5 pt) pthread_t th1, th2;
printf ("Je suis thread1,"); sem_init (&my_sem1, 0 ,0); (0.5 pt)
sem_post(&my_sem2) (0.5 pt) sem_init (&my_sem2, 0 ,1); (0.5 pt)
} } pthread_create (&th1, NULL,&thread1, NULL) ;
pthread_create (&th2, NULL,&thread2, NULL) ;
pthread_join (&th1, NULL);
pthread_join (&th2, NULL);

A. ABBAS 1 Bon courage


Examen système d'exploitation Département d’informatique, Université de Bouira

Question :
1. Complétez ce programme pour qu'il affiche la séquence suivante : Je suis thread1, Je suis thread2,
Je suis thread1, Je suis thread2,....
2. Utiliser le programme précédent pour écrire un autre programme qui initialise une variable entière
cpt à 1 et qui crée deux threads p1 et p2. Le thread p1 incrémente cpt 10000 fois et le thread p2
décrémente cpt 10000 fois. Utiliser un sémaphore pour résoudre le problème de l’accès concurrent à
la variable cpt.
#include <stdio.h> void* p2(void* arg){
#include <stdlib.h> int i=0;
#include <unistd.h> while (i<10000){
#include <pthread.h> sem_wait(&semaphore); (0.5 pt)
#include <semaphore.h> cpt -=1;
sem_t semaphore; (0.5 pt) sem_post(&semaphore); (0.5 pt)
int cpt =1; (0.5 pt) i++;
void* p1(void* arg){ }
int i=0; }
while (i<10000){ int main(void) {
sem_wait(&semaphore); (0.5 pt) pthread_t tache1, tache2;
cpt +=1; sem_init(&semaphore, 0, 1); (0.5 pt)
sem_post(&semaphore); (0.5 pt) pthread_create (&tache1, NULL, &fonc1, NULL);
i++; pthread_create (&tache2, NULL, &fonc2, NULL);
} pthread_join(tache1, NULL);
} pthread_join(tache2, NULL);
printf("cpt =%d:\n", cpt ); (0.5 pt)
return 0;
}

A. ABBAS 2 Bon courage


Test 2 - version 1

Exo1: 3 pts
Quelle est la différence entre section critique et ressource critique ?
a. Une section critique (SC): est un ensemble d'instruction d'un programme qui peuvent engendrer
des résultats imprévisibles (ou incohérents) lorsqu'elles sont exécutées simultanément par des
processus différents. Une SC est une suite d'instructions qui opèrent sur une ou plusieurs ressources
partagées (critiques) et qui nécessitent une utilisation exclusive de ces ressources.
b. On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès concurrent
(ou simultané) par plusieurs processus.
Exo2: 7 pts
Soit le graphe de processus suivant:
A

B E
C

Réaliser la synchronisation des ces processus en utilisant les sémaphores


Sémaphore SA=0, SD=0

PA (){ PB (){ PC (){ PE (){ PD (){


I; P(SA) P(SA) I; P(SD);P(SD
V(SA);V(S I; I; V(SD); ); P(SD) ;
A); V(SD); V(SD); } I;
} } } }

Exo3: 5 pts
Donner le rôle de chaque élément ci-dessous.
fork() ; est un moyen offre par SE afin de créer des processus, par duplication d'un processus existant.
wait() ; Permet au père d'attendre le premier enfant qui se termine
pthread_join() ; Attendre la fin d'exécution d’un thread
sem_wait() ; équivalente à l'opération P (S) et retourne toujours 0
Local_irq_disable(); masquées les interruptions.
Test 2 - version 2

Exo1: 3 pts
La valeur initiale d’un sémaphore est égale à K, que représente cette valeur ?
K représente le nombre d'unités d'une ressource R utilisables par un ou plusieurs processus à un instant
t. On peut aussi définir k comme le nombre d'autorisations d'accès à une section critique à un instant t.
Exo2: 7 pts
Soit le graphe de processus suivant:
A

B E
C

Réaliser la synchronisation des ces processus en utilisant les sémaphores

Sémaphore SA=0, SD=0


PA (){ PB (){ PC (){ PE (){ PD (){
I; P(SA) I; P(SA) P(SD);P(SD);
V(SA);V(SA); I; V(SD); I; P(SD) ;
} V(SD); } V(SD); I;
} } }

Exo3: 5 pts
Donner le rôle de chaque élément ci-dessous.
waitpid(); Attendre l’enfant d’identificateur pid se termine
kill() ; Le processus père mis fin à l'exécution de l'un de ces fils
while (wait(NULL)>=0) ; Attendre la fin de chaque enfant
pthread_self() ; Retourne le TID du thread
sem_post()): est équivalente a l'opération V(S)
Test 2 - version 3

Exo1: 6 pts
Quelles sont les opérations d'un sémaphore qui s’exécutent d’une manière indivisible ?
Et que ce qu'une section critique.
Les opération d'un sémaphore qui s'exécute d'une manière indivisible sont P(S) et V(S)
On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès
concurrent (ou simultané) par plusieurs processus.

Exo2: 9 pts
Écrire un programme qui crée 2 processus fils, l'un des fils affiche les entiers de 1 à
10, l'autre fils affiche les entiers de 11 à 20. Le père devra attendre la fin de ses deux
fils et afficher quel a été le premier processus qui a terminé.
1. #include <sys/types.h>
2. #include <unistd.h>
3. #include <stdio.h>
4. int main(int argc, char **argv) {
5. pid_t p1,p2,premier;
6. int i;
7.
8. p1 = fork();
9. if (p1 == 0){
10. for (i=1; i<11; i++)
11. printf("%d \n", i);
12. exit() ;
13. }
14.
15. p2 = fork();
16. if (p2 == 0){
17. for (i=11; i<21; i++)
18. printf("%d \n", i);
19. exit() ;
20. }
21.
22. premier =wait(NULL);
23. wait(NULL);
24.
25. printf(" le premier processus qui a terminé est %d \n", premier);
26. return 0;
}

-----------------------------------------------------------------------------------------------------------------
Test 2 - version 4

Exo1: 5 pts
La valeur initiale d’un sémaphore est égale à K, que représente cette valeur ?
K représente le nombre d'unités d'une ressource R utilisables par un ou plusieurs processus à
un instant t. On peut aussi définir k comme le nombre d'autorisations d'accès à une section
critique à un instant t.

Exo2: 10 pts
Écrire un programme qui crée 3 processus fils, chaque fils affiche son PID et se
termine. Le père devra attendre la fin de ses 3 fils et afficher quel a été le dernier
processus qui a terminé.

27. #include <sys/types.h>


28. #include <unistd.h>
29. #include <stdio.h>
30. int main(int argc, char **argv) {
31. pid_t p,dernier;
32. int i, n=3;
33. for (i=0; i<n; i++) {
34. p = fork();
35. if (p == 0){
36. printf(" Processus %d \n", getpid());
37. exit() ;
38. }
39. }
40. wait(NULL);
41. wait(NULL);
42. dernier =wait(NULL);
43. printf(" le dernier processus qui a terminé est %d \n", dernier);
44. return 0;
45. }
Solution Test groupe 1

Exo1: 3 pts
Quelle est la différence entre section critique et ressource critique ?
a. Une section critique (SC): est un ensemble d'instruction d'un programme qui peuvent
engendrer des résultats imprévisibles (ou incohérents) lorsqu'elles sont exécutées simultanément par
des processus différents. Une SC est une suite d'instructions qui opèrent sur une ou plusieurs
ressources partagées (critiques) et qui nécessitent une utilisation exclusive de ces ressources.
b. On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès
concurrent (ou simultané) par plusieurs processus.
Exo2: 7 pts
Soit le graphe de processus suivant:
A

B E
C

D
Réaliser la synchronisation des ces processus en utilisant les sémaphores
Sémaphore SA=0, SD=0

PA (){ PB (){ PC (){ PE (){ PD (){


I; P(SA) P(SA) I; P(SD);P(SD);
V(SA);V(SA); I; I; V(SD); P(SD) ;
} V(SD); V(SD); } I;
} } }

Exo3: 5 pts
Expliquez pas-à-pas comment s'exécute le programme suivant. (3pts)
1. main () {
2. int x ;
3. x=0 ;
4. pid_t pro;
5. pro=fork();
6. if (pro==0)
7. x=1
8. prinf(‘‘x=%d\n’’,x) ;
9. else
10. prinf(‘‘x=%d\n’’,x) ;
}

inst4: déclaration d'une varaible de type pid_t


inst5: création du processus fils suite à l'appel de la fonction fork() et affectation de la valeur de retour
à la variable pro
inst6: test la valeur de pro, si elle égale à 0 alors on est dans le fils
inst7: le processus fils affecte 1 à x
inst8: le processus fils affiche: x=1
inst8: si la valeur de pro différente de 0 alors on est dans le père
inst9: le processus père affiche: x=0
Solution Test groupe 2

Exo1: 3 pts
La valeur initiale d’un sémaphore est égale à K, que représente cette valeur ?
K représente le nombre d'unités d'une ressource R utilisables par un ou plusieurs processus à un instant
t. On peut aussi définir k comme le nombre d'autorisations d'accès à une section critique à un instant t.

Exo2: 7 pts
Soit le graphe de processus suivant:
A

B E
C

Réaliser la synchronisation des ces processus en utilisant les sémaphores

Sémaphore SA=0, SD=0


PA (){ PB (){ PC (){ PE (){ PD (){
I; P(SA) P(SA) P(SA) P(SD);P(SD);
V(SA);V(SA); I; I; I; P(SD) ;
V(SA) V(SD); V(SD); V(SD); I;
} } } } }

Exo3: 5 pts
Expliquez pas-à-pas comment s'exécute le programme suivant. (3pts)
11. main () {
12. int x ;
13. x=0 ;
14. if (fork() !=0)
15. x=1 // processus père affecte 1 à x
16. else
17. x=2 // processus fils affecte 2 à x
18. prinf(‘‘x=%d\n’’,x) ;
}

inst4: appel de la fonction fork() pour créer un processus fils et test la valeur de retour de la
fork s'elle est différente de zéro;
inst5: Si la valeur de retour de fork () différente de zéro alors on est dans le père qui affecte 1
àx
inst7: Si la valeur de retour de fork () égale à zéro alors on est dans le fils qui affecte 2 à x
inst8: le processus père affiche: x=1 et le processus fils affiche x=2
Solution Test groupe 1

Exo1: 3 pts
Quelle est la différence entre section critique et ressource critique ?
a. Une section critique (SC): est un ensemble d'instruction d'un programme qui peuvent
engendrer des résultats imprévisibles (ou incohérents) lorsqu'elles sont exécutées simultanément par
des processus différents. Une SC est une suite d'instructions qui opèrent sur une ou plusieurs
ressources partagées (critiques) et qui nécessitent une utilisation exclusive de ces ressources.
b. On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès
concurrent (ou simultané) par plusieurs processus.
Exo2: 7 pts
Soit le graphe de processus suivant:
A

B E
C

D
Réaliser la synchronisation des ces processus en utilisant les sémaphores
Sémaphore SA=0, SD=0

PA (){ PB (){ PC (){ PE (){ PD (){


I; P(SA) P(SA) I; P(SD);P(SD);
V(SA);V(SA); I; I; V(SD); P(SD) ;
} V(SD); V(SD); } I;
} } }

Exo3: 5 pts
Expliquez pas-à-pas comment s'exécute le programme suivant. (3pts)
1. main () {
2. int x ;
3. x=0 ;
4. pid_t pro;
5. pro=fork();
6. if (pro==0)
7. x=1
8. prinf(‘‘x=%d\n’’,x) ;
9. else
10. prinf(‘‘x=%d\n’’,x) ;
}

inst4: déclaration d'une varaible de type pid_t


inst5: création du processus fils suite à l'appel de la fonction fork() et affectation de la valeur de retour
à la variable pro
inst6: test la valeur de pro, si elle égale à 0 alors on est dans le fils
inst7: le processus fils affecte 1 à x
inst8: le processus fils affiche: x=1
inst8: si la valeur de pro différente de 0 alors on est dans le père
inst9: le processus père affiche: x=0
Solution Test groupe 2

Exo1: 3 pts
La valeur initiale d’un sémaphore est égale à K, que représente cette valeur ?
K représente le nombre d'unités d'une ressource R utilisables par un ou plusieurs processus à un instant
t. On peut aussi définir k comme le nombre d'autorisations d'accès à une section critique à un instant t.

Exo2: 7 pts
Soit le graphe de processus suivant:
A

B E
C

Réaliser la synchronisation des ces processus en utilisant les sémaphores

Sémaphore SA=0, SD=0


PA (){ PB (){ PC (){ PE (){ PD (){
I; P(SA) P(SA) P(SA) P(SD);P(SD);
V(SA);V(SA); I; I; I; P(SD) ;
V(SA) V(SD); V(SD); V(SD); I;
} } } } }

Exo3: 5 pts
Expliquez pas-à-pas comment s'exécute le programme suivant. (3pts)
11. main () {
12. int x ;
13. x=0 ;
14. if (fork() !=0)
15. x=1 // processus père affecte 1 à x
16. else
17. x=2 // processus fils affecte 2 à x
18. prinf(‘‘x=%d\n’’,x) ;
}

inst4: appel de la fonction fork() pour créer un processus fils et test la valeur de retour de la
fork s'elle est différente de zéro;
inst5: Si la valeur de retour de fork () différente de zéro alors on est dans le père qui affecte 1
àx
inst7: Si la valeur de retour de fork () égale à zéro alors on est dans le fils qui affecte 2 à x
inst8: le processus père affiche: x=1 et le processus fils affiche x=2
Université de Bouira - Département d’Informatique Année 2020-2021
Module : Systèmes d'Exploitation 3ème année Licence SI
Série TD N° 1

Exercice 1 :
Écrire un algorithme puis réaliser un découpage en tâches t1,...,tn de l'expression suivante:

y := ( (a+b) / (c - d) + (e*f)) + (a+b) * (c-d)

En vous servant de la définition de la condition de Bernstein, étudier la possibilité de paralléliser cette


expression

Exercice 2 :
Combien de processus le programme suivant crée-t-il ?
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main() {
fork();
fork();
fork();
return EXIT_SUCCESS;
}
Exercice 3 :
. Dessiner l’arbre généalogique des processus engendrés par le programme ?
# include <unistd.h>
# include <stdio.h>
int main() {
pid_t pid; int i;
for (i=0; i<3;i++) {
pid = fork();
if (pid < 0 ){
printf ("le fork ( ) a échoué \n") ;
}
else if (pid == 0){
printf(" je suis le processus : %d, mon père est : %d\n", getpid(), getppid()) ;
}
else{
printf("je suis le processus : %d, mon père est : %d\n", getpid(), getppid()) ;
}
} return 0 ;
}

Exercice 4 :
Écrire un programme en C qui lance 5 fils et attend la fin de leur exécution pour se terminer.
Nom:
Test de TD
Prénom:
Grroupe :

Exercice 1: Quelle est la différence entre une ressource critique et une section critique ?

a. Une section critique (SC): est un ensemble d'instruction d'un programme qui peuvent
engendrer des résultats imprévisibles (ou incohérents) lorsqu'elles sont exécutées
simultanément par des processus différents. Une SC est une suite d'instructions qui opèrent
sur une ou plusieurs ressources partagées (critiques) et qui nécessitent une utilisation
exclusive de ces ressources.
b. On appelle ressource critique tout objet informatique qui peut faire l'objet d'un accès
concurrent (ou simultané) par plusieurs processus.
Exercice 2: Soit l'expression suivante :

e := ((b - d) * (a+ c) + (e*f)) / (a+c)

Découper la en tâches (sans l'ajout de vraiables) et en vous servant de la définition de la


condition de Bernstein, donner le graphe de précédence correspondant.
t1: b = b - d t2 t1 t3
t2: a = a + c
t3: e = e * f
t4: b = b * a t4
t5: b = b + e
t6: e = b / a t5
t6

Exercice 3: Soit le graphe de processus suivant:


A

B E
C

Réaliser la synchronisation des ces processus en utilisant les sémaphores


Sémaphore SA=0, SD=0
PA (){ PB (){ PC (){ PE (){ PD (){
I; P(SA) I; P(SA) P(SD);P(SD);
P(SD) ;
V(SA);V(SA); I; V(SD); I;
I;
} V(SD); } V(SD);
}
} }
Nom:
Test 2 de TD SE L3- INFO
Prénom:
Groupe :
Groupe 2

3+6+6

Exercice 1: Les moniteurs sont considérés comme des outils de synchronisation "avancés"
par rapport aux sémaphores. Expliquez brièvement pourquoi. ?
les moniteurs cachent les détails de synchronisation (pas P(s) V(S) dans le code des
processus). Le code des processus devient moins lourd.
Permet de regrouper dans un module spécial appelé moniteur toutes les sections
critiques d'un même problème. Avoir un seul processus active dans le moniteur à tout
instant

Exercice 2: Considérez les 3 processus A, B et C concurrents suivants :


A B C
Où ai, bi et ci, pour i=1,2, sont des actions atomiques. a1; a2; b1; b2; c1; c2;

• Utilisez les sémaphores pour forcer l’exécution des actions du processus A avant celles de
B et C. Les actions de B et C s’exécutent en concurrence (en parallèle).

Exercice 2: On considère trois processus P1, P2 et P3 concurrents. Les codes des processus
P1, P2 et P3 sont les suivants:
Intégrer des sémaphores afin d'afficher la séquence suivante:
1,1,1, 2,3, 1,1,1, 2,3, 1,1,1, 2,3, .....

S1=3,S2=0,S3=0
P1 ( ) { P2 ( ) { P3 ( ) {
while(TRUE) { while(TRUE) { while(TRUE) {
p(s1); p(s2); p(s2); p(s2); p(s3);
printf("1,"); printf("2,"); printf("3,");
V(S2); V(S3); V(S1);V(S1);V(S1) ;
}} }} }}
Test 2 de TD SE L3- INFO

Nom:
Prénom:
Groupe :
Groupe 1
3+6+6

Exercice 1: Quels sont les avaantages de l’utilisation de moniteurs pour synnchroniser


l’exécution des processus?
Permet de regrouper dans un module spécial appelé moniteur to toutes les sections
critiques d'un même problème.
p

Exercice 2: Considérez les pprocessus P1, P2, P3 et P4, et les sémaphhores S1 et S2. Les
processus sont lancés en concuurrence.

Donnez les ordres d’exécutionn des processus et des opérations atomiques a, b, c, d, e, f, g et h.

a,b, e, f, c, d,, g, h ----> P1 P3 P2 P4


P
a,b, g, h, c, dd, e, f ----> P1 P4 P2 P33
c, d, e, f, a, b
b, g, h ----> P2 P3 P1 P4
P
c, d, g, h, a, b, e, f ----> P2 P4 P1 P3
P
Exercice 3: Soient N processsus parallèles ayant un point de rendez-vvous. Un processus
arrivant au point de rendez-voous se met en attente s'il existe au moins un autre processus qui
n'y est pas arrivé. Le dernier ar
arrivé réveillera les processus bloqués.
• Donner la solution à ce prooblème en utilisant les sémaphore
Test 2 de TD SE L3- INFO

Nom:
Prénom: Groupe 3
Groupe :

3+6+6
Exercice 1: Les moniteurs sont considérés comme des outils de synchronisation. Expliquez
brièvement le rôle des primitives wait() et signal() ??
wait(x) : suspend ou bloque l'exécution du processus (thread) appelant wait et le met en
attente de x et autorise un autre processus en attente du moniteur a y entrer dans ce moniteur.
signal(x) : débloqué un processus en attente de la condition x.

Exercice 2:Soient deux variables x et y communes à deux processus déclarées comme suit :
int x = 0 ; int y = 0 ;
Les deux processus exécutent les codes suivants :
Processus P1{ Processus P2{
x = x + 1; x = x * 2;
y = y + 1; y = y * 2;
printf("x=%d,y=%d\n", x, y); } printf("x=%d, y=%d\n", x, y);}

1. Ces processus s'exécutent sur un système dont la politique d'ordonnancement est du type
temps partagé. Quelles peuvent être les couples de valeurs affichées par chacun des deux
processus ? 6
Les couples de valeurs affichées

P1 (x, y)={ (1,1); (2,1); (2,2)}

P2 (x, y)={ (0,0) ; (2,2); (2,0); (1,2); (1,1); (2,1) }

2. Utilisez les sémaphores pour synchroniser les deux processus au niveau des sections
critiques, puis donnez les couples de valeurs affichées par chacun des deux processus. 6

On utilise un sémaphore S initialisé ainsi : S=1

Processus P1{ Processus P2{


P (S); P (S);
x = x + 1; x = x * 2;
y = y + 1; y = y * 2;
printf("x=%d,y=%d\n", x, y); printf("x=%d, y=%d\n", x, y);
V (S); } V (S); }

couples de valeurs affichées

P1 (x, y)={ (1,1) }

P2 (x, y)={ (0,0) ; (2,2) }


Nom :

Prénom :

Section : Test TD M1

Exercice 1 4pts: On considère un système de fichiers tel que l’information concernant un


fichier est accessible à partir de son i-nœud. On suppose que : Le système de fichiers utilise
des blocs de données de taille 1Ko. L’i-nœud de chaque fichier contient 10 pointeurs directs
sur des blocs de données, 1 pointeur indirect simple, 1 pointeur indirect triple. Les pointeurs
sont sur 4 octets.
1. Quelle est la taille de la structure d'adressage ?

3k +2562k

2. Quelle est le nombre de blocs de donnée que ce système de fichiers peut supporter ?

266+2563

Exercice 2 6pts: Un disque dur de 1 Go est formaté en FAT16.


 Quelle est la taille de ses clusters
taille / nombre de clusters=230/216=214 octets=16 Ko
 Quelle est la taille de la FAT?
16 bits * 216=2octet * 216=27 ko=128 ko

Exercice 3 2,5pts: Donner les instructions permettant de verrouiller - déverrouiller un


fichier [Link]
verrouiller un fichier déverrouiller un fichier
fd = open("[Link]",O_RDWR);
S=lockf(fd, F_LOCK,10); S=lockf(fd, F_ULOCK, 0);
Exercice 4 2,5pts: Soit un système à partitions dynamique de mémoire avec allocation
contigüe. A un instant t les partitions libres sont 100K, 500k, 200K, 300k et 600K. On
considère une liste d’arrivée des processus qui demandent +A(212K), +B(417K), +C(112K)
et +D(426K).
Donner les images successifs de mémoire suit à l'utilisation de la stratégie Best Fit

Vous aimerez peut-être aussi