TP4 - IPC- Moniteur, Signaux et Pipe
Ce TP explore la communication et la synchronisation entre processus à travers plusieurs mécanismes : moniteurs, signaux et pipes.
D'après le document TP4 - IPC- Moniteur, Signaux et Pipe
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Programming, Inter-Process Communication, Synchronization · DOCX · 7 pages · 2014
Ce TP explore la communication et la synchronisation entre processus à travers plusieurs mécanismes : moniteurs, signaux et pipes. Il propose des exercices pratiques pour implémenter des solutions classiques de synchronisation concurrente, notamment le problème des lecteurs/rédacteurs, le problème des philosophes, la gestion d’un compte bancaire partagé entre processus, et la synchronisation via signaux pour un calcul simple. Pour réaliser ce TP, il est nécessaire de maîtriser les concepts de base des systèmes d’exploitation, la programmation concurrente, ainsi que les primitives IPC (Inter-Process Communication) sous Unix.
Objectifs
- Comprendre et implémenter le concept de moniteur pour gérer la synchronisation des processus.
- Résoudre les problèmes classiques de synchronisation : lecteurs/rédacteurs et philosophes.
- Utiliser les sémaphores et la mémoire partagée pour synchroniser plusieurs processus.
- Mettre en œuvre la synchronisation par signaux entre un processus père et un processus fils.
- Développer des programmes capables de gérer des accès concurrents à des ressources partagées.
Prérequis et configuration
- Connaissances en programmation C et en systèmes d’exploitation.
- Compréhension des concepts de processus, threads, sémaphores, mémoire partagée et signaux.
- Environnement Unix/Linux avec accès aux bibliothèques
ipc.h,sem.h, etshm.h. - Compilateur C (gcc ou équivalent) et outils de débogage.
- Accès à un terminal pour exécuter et tester les programmes.
Exercice 1 : Solution du problème des lecteurs/rédacteurs avec un moniteur
Dans cet exercice, vous devez écrire un moniteur qui gère l’accès concurrent à une ressource partagée par plusieurs lecteurs et rédacteurs. Le moniteur doit garantir que plusieurs lecteurs peuvent lire simultanément, mais qu’un rédacteur a un accès exclusif.
Le moniteur contient les variables et procédures suivantes :
Monitor LectRed_Pb {
private int ecr; // drapeau occupation par un rédacteur
private int nblect; // nombre de lecteurs en cours
private condition Lecture;
private condition Ecriture;
public void DebutLire() {
if (ecr == 1) wait(Lecture);
nblect = nblect + 1;
while (not Empty(Lecture))
signal(Lecture); // Réveil du 1er lecteur qui réveillera les suivants
}
public void FinLire() {
nblect = nblect - 1;
if (nblect == 0) signal(Ecriture); // le dernier lecteur peut réveiller un rédacteur
}
public void DebutEcrire() {
if ((ecr == 1) || (nblect > 0)) wait(Ecriture); // voie libre pour la rédaction
ecr = 1;
}
public void FinEcrire() {
ecr = 0; // rédaction terminée
if (not Empty(Lecture))
signal(Lecture); // Réveiller prioritairement un lecteur
else if (not Empty(Ecriture))
signal(Ecriture); // à défaut réveiller un rédacteur
}
// Initialisation des variables
ecr = 0;
nblect = 0;
}
Ce qu’il faut faire :
- Implémenter ce moniteur en C ou dans un langage supportant les moniteurs.
- Tester les procédures
DebutLire,FinLire,DebutEcrireetFinEcriredans un contexte concurrent.
Pourquoi : Ce moniteur assure une synchronisation correcte entre lecteurs et rédacteurs, évitant les conflits d’accès.
Résultat attendu : Plusieurs lecteurs peuvent lire simultanément, mais un rédacteur attend que tous les lecteurs aient fini avant d’écrire. Aucun accès concurrent non protégé ne doit se produire.
Exercice 2 : Solution du problème des philosophes avec un moniteur
Ce problème classique illustre la synchronisation de plusieurs processus partageant des ressources limitées (fourchettes). Le moniteur doit permettre à chaque philosophe de prendre deux fourchettes adjacentes pour manger sans provoquer d’interblocage.
Monitor Philosoph_Pb {
#define LIBRE 0;
#define OCCUPE 1;
private int Fourchette[5];
private int j;
private condition condManger;
public void Demande_a_manger(int i) {
while ((Fourchette[i] == OCCUPE) || (Fourchette[(i+1)%5] == OCCUPE)) {
signal(condManger);
wait(condManger);
}
Fourchette[i] = OCCUPE;
Fourchette[(i+1)%5] = OCCUPE;
printf("Le philosophe %d obtient les fourchettes F%d et F%d et mange \n", i, i, (i+1)%5);
}
public void Fini_de_Manger(int i) {
Fourchette[i] = LIBRE;
Fourchette[(i+1)%5] = LIBRE;
signal(condManger);
printf("Le philosophe %d libere ses fourchettes F%d et F%d\n", i, i, (i+1)%5);
}
// Initialisation des fourchettes
for (j = 0; j < 5; j++) Fourchette[j] = LIBRE;
}
Ce qu’il faut faire :
- Implémenter ce moniteur en respectant les définitions des états des fourchettes.
- Simuler plusieurs philosophes demandant à manger et libérant les fourchettes.
Pourquoi : Ce moniteur évite les blocages et garantit que chaque philosophe peut manger dès que ses fourchettes sont disponibles.
Résultat attendu : Les philosophes mangent sans interblocage, les messages d’obtention et de libération des fourchettes sont affichés correctement.
Exercice 3 : Synchronisation de processus avec sémaphores et mémoire partagée
Ce TP vous demande d’implémenter une solution inter-processus au problème de gestion d’un compte bancaire partagé. Le processus père effectue des dépôts fixes de 100$, tandis que deux processus fils effectuent des retraits de 80$ chacun.
Le but est d’utiliser les sémaphores pour assurer l’exclusion mutuelle et la synchronisation des opérations.
// Variables partagées
int dep = 100;
int ret = 80;
int compte;
void deposit() {
while (1) {
P(m); // sémaphore d'exclusion mutuelle initialisé à 1
compte += dep;
printf("Processus père deposits %ld \n", dep);
V(m);
V(depot); // sémaphore depot initialisé à 0
if ((compte mod ret) == 0) V(depot);
sleep(5);
}
}
void withdraw() {
while (1) {
P(depot);
P(m);
compte = compte - ret;
printf("Processus fils withdraws %d \n", ret);
V(m);
}
}
Ce qu’il faut faire :
- Initialiser les sémaphores
m(exclusion mutuelle) etdepot(synchronisation des retraits). - Créer un processus père qui effectue les dépôts et deux processus fils qui effectuent les retraits.
- Assurer que les retraits ne se produisent que si le compte dispose d’un solde suffisant.
Pourquoi : Cette solution illustre la synchronisation inter-processus avec sémaphores et mémoire partagée, évitant les conditions de course.
Résultat attendu : Le compte est mis à jour correctement, les dépôts et retraits s’alternent sans conflit, et les messages d’opérations sont affichés.
Exercice 4 : Synchronisation par signaux entre processus père et fils
Dans cet exercice, vous devez écrire un programme où un processus père crée un fils. Ils partagent un segment de mémoire dans lequel le père écrit un opérateur et deux opérandes. Le fils attend un signal pour lire ces données, effectuer l’opération (addition, soustraction, multiplication ou division) et afficher le résultat.
La synchronisation est assurée par un signal (par exemple SIGUSR1) envoyé par le père au fils après l’écriture.
Étapes à suivre :
- Définir un segment de mémoire partagé contenant les variables
operateur,operande1etoperande2. - Écrire une fonction handler dans le fils associée au signal SIGUSR1 qui lit les variables partagées, effectue l’opération et affiche le résultat.
- Dans le père, écrire les données dans la mémoire partagée puis envoyer le signal SIGUSR1 au fils.
- Ajouter un
wait()dans le père pour attendre la fin du fils avant de terminer.
Pourquoi : Cette méthode garantit la cohérence des données en synchronisant la lecture et l’écriture via un signal.
Résultat attendu : Le fils affiche le résultat correct de l’opération après réception du signal, démontrant la synchronisation effective.
Résultats attendus
- Pour le moniteur lecteurs/rédacteurs : accès exclusif garanti pour les rédacteurs, accès simultané possible pour plusieurs lecteurs.
- Pour le moniteur philosophes : absence d’interblocage, chaque philosophe mange lorsqu’il obtient ses fourchettes, messages d’état corrects.
- Pour la gestion du compte bancaire : les dépôts et retraits s’enchaînent sans conflit, le solde est cohérent, les messages d’opérations sont affichés.
- Pour la synchronisation par signaux : le fils affiche le résultat correct de l’opération après réception du signal, démontrant la synchronisation effective.
Pièges courants
- Dans le moniteur lecteurs/rédacteurs, ne pas réveiller correctement les lecteurs ou rédacteurs peut entraîner un blocage ou une famine.
- Dans le problème des philosophes, un mauvais ordre de prise des fourchettes peut provoquer un interblocage.
- Pour la synchronisation avec sémaphores, une mauvaise initialisation ou un oubli de libération peut bloquer les processus indéfiniment.
- Dans la synchronisation par signaux, oublier d’installer le handler ou de gérer correctement le segment mémoire partagé peut causer des incohérences ou des plantages.
- Ne pas utiliser
wait()dans le père pour attendre le fils peut entraîner la terminaison prématurée du père avant la fin du traitement.
Commentaires
Aucun commentaire pour le moment. Posez la première question.