REPUBLIQUE ALGERIENNE DEMOCRATIQUE ET POPULAIRE
MINISTERE DE L’ENSEIGNEMENT SUPERIEUR ET DE LA RECHERCHE
SCIENTIFIQUE UNIVERSITE M’HAMED BOUGARA-BOUMERDES
Faculté Des Sciences Département d’Informatique
Travail Pratique
Sujet :
Synchronisation des processus à l’aide des sémaphores
Module : Système d’exploitation 2
Année Scolaire : 2022 / 2023
Introduction :
Un sémaphore S, est une variable entière associée à une file d’attente f(s), sous UNIX, L’implantation
Unix des sémaphores permet l’acquisition simultanée d’exemplaires multiples de plusieurs ressources, avec
cette technique nous allons voir comment synchroniser N processus parallèles ayant un point de rendez-vous,
et qui font l’objet de notre TP.
I. Le code propose pour résoudre le problème :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define NUM_PROCESSES 3
int main() {
key_t key = 1234 ;
int semid = semget(key, 2, IPC_CREAT | 0666); // Création des sémaphores
// Initialisation des sémaphores
semctl(semid, 0, SETVAL, 1); // mutex
semctl(semid, 1, SETVAL, 0); // semWakeUp
int shmid = shmget(key, sizeof(int), IPC_CREAT | 0666); // Création du segment de mémoire partagée
int* order = (int*)shmat(shmid, NULL, 0); // Attache du segment de mémoire partagée
*order = 0; // Initialisation de l'ordre d'arrivée
for (int i = 0; i < NUM_PROCESSES; i++) {
pid_t pid = fork(); // Création des processus
if (pid == 0) {
// Arrivée au point de rendez-vous
semop(semid, &(struct sembuf){0, -1, 0}, 1); // P(mutex)
(*order)++; // Incrément de l'ordre d'arrivée
printf("Arrivée du processus %d\n", getpid());
semop(semid, &(struct sembuf){0, 1, 0}, 1); // V(mutex)
// Attente jusqu'à la fin de tous les processus
if (*order == NUM_PROCESSES) {
printf("Dernier processus arrivé, réveil des autres processus\n");
semop(semid, &(struct sembuf){1, NUM_PROCESSES, 0}, 1); // V(semWakeUp) avec un count
égal à NUM_PROCESSES
}
// Attente jusqu'à être réveillé
semop(semid, &(struct sembuf){1, -1, 0}, 1); // P(semWakeUp)
// Affichage du PID dans l'ordre inversé
printf("Suite du processus %d\n", getpid());
// Libération du segment de mémoire partagée
shmdt(order);
exit(0);
}
}
// Processus parent
for (int i = 0; i < NUM_PROCESSES; i++) {
wait(NULL); // Attente de la fin de tous les processus enfants
}
// Libération des ressources (sémaphores et segment de mémoire partagée)
semctl(semid, 0, IPC_RMID, 0);
semctl(semid, 1, IPC_RMID, 0);
shmctl(shmid, IPC_RMID, 0);
return 0;
}
II. L’explication de code propose :
Pour inverser l'ordre d'exécution des processus au point de rendez-vous, nous avons suivis les étapes suivantes :
On a Créé un segment de mémoire partagée pour stocker la variable partagée « order », initialisée à 0. Cette
variable order représentera l'ordre d'arrivée des processus.
On a Créé deux sémaphores, mutex et semWakeUp. Mutex pour assurer l’exclusion mutuelle de la variable
partagee et est initialisé à 1 et semWakeUp pour bloquer les processus dans le point d’attende des processus et
pour réveiller ces processus aussi et est initialisé à 0.
Chaque processus qui arrive au point de rendez-vous suit les étapes suivantes :
- Il attend que mutex soit disponible (P(s)).
- Il incrémente la variable order pour indiquer son arrivée au point de rendez-vous.
- Il affiche le PID du processus.
- Il libère mutex (V(s)).
Une fois tous les processus arrivés au point de rendez-vous, le dernier processus arrivé procède comme suit :
- Il attende que mutex soit disponible (P(s)).
- Il affiche à nouveau le PID du processus pour confirmer l'ordre.
- Il libère mutex (V(s)).
- Il réveille les processus bloqués en effectuant V(semWakeUp) (opération de libération sur semWakeUp).
Chaque processus, une fois réveillé, suit les étapes suivantes :
- Il effectue P(semWakeUp) pour attendre jusqu'à ce que le dernier processus arrive.
- Il affiche à nouveau le PID du processus pour confirmer l'ordre inversé.
- Il libère semWakeUp (V(s)).
En utilisant ce mécanisme, les processus arriveront au point de rendez-vous et s'endormiront jusqu'à ce que le dernier
processus arrive. Le dernier processus à arriver les réveillera tous en libérant semWakeUp. Ainsi, les processus
continueront leur exécution dans l'ordre inverse de leur arrivée.
III. Exemple d’exécution du code :