TP4 - IPC- Moniteur, Signaux et Pipe

1/7
100%

Ecole Nationale des Sciences de l’Informatique A. U. : 2014/2015

Systèmes d’exploitation & Programmation Concurrente II2

TP4 - IPC- Moniteur, Signaux et Pipe ========================================================

Exercice 1 (Moniteur)

1- Ecrire une solution correspondant au problème des lecteurs/rédacteurs traité en classe en utilisant le concept de moniteur. (Le moniteur correspondant doit contenir la déclaration de toutes les procédures et variables nécessaires et l’initialisation de ces dernières).

Monitor LectRed\_Pb {

private int ecr ; //drapeau occupation par un rédacteur

private int nblect; //nbre 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

Publicité

ecr=1;

}

public void FinEcrire () {

ecr=0; //redaction 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;

}

Exercice 2 (Moniteur)

2- Ecrire une solution correspondant au problème des philosophes traité en classe en utilisant le concept de moniteur.

Monitor Philosoph\_Pb {

#define LIBRE=0;

#define OCCUPE=1;

private int Fourchette[5];

private int j;

private condition condManger;

Publicité

/\---------------------\/

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", (int)i,(int)i, ((int)i+1)%5);

}

public void Fini\_de\_Manger(int i){

Fourchette[i]=LIBRE;

Fourchette[(i+1)%5] = LIBRE;

signal(condManger);

printf("Le philosope %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;

}

Exercice 3 (Synchronisation de Processus - Implémentation)

Le but de cet exercice est d’utiliser les modules « ipc.h », « sem.h », et « shm.h » afin de réaliser une synchronisation inter-processus.

Pour celà, vous êtes appelés à implémenter la solution au problème de « gestion de compte bancaire » [traité dans exercice 2 du TP2] en utilisant une synchronisation inter-processus (et non pas une solution multithreadée).

Publicité

Pour cet exercice, on suppose qu’il y a un processus dépositeur (le processus père) et deux processus de retrait (les 2 processus fils). On suppose que montant déposé chaque fois par le processus père est fixe et égal à 100$ et celui retiré par un processus fils est égal à 80$.

Note: Pour vous aider, vous pouvez vous inspirer de l’exemple donné dans le complément du chapitre 4.

1- Implémentez la solution correspondante à ce problème en utilisant une synchronisation inter-processus.

2- Donnez un imprime-écran de votre solution montrant les différentes opérations de dépôt et de retrait bloqué et réussi.

Réponse:

Ici, vu que les montants de dépôt et de retrait ont été fixés à 80 et 100, le problème peut être résolu avec les sémaphores en utilisant les fonctions suivantes :

//Ces variables sont partagées entre les processus

int dep=100 ;

int ret=80 ;

int compte;

void deposit() {

while (1){

P(m); //m semaphore d’exclusion mutuelle (retrait/dépôt) initialisé à 1

compte+=dep;

printf(“Processus père deposits %ld \n”, dep);

V(m);

V(depot); // depot semaphore initialisé à zéro

if((compte mod ret ==0)) V(depot);

sleep (5);

}

}

void withdraw() {

while (1){

Publicité

P(depot);

P(m);

compte = compte - ret;

printf(“Processus fils withdraws %d \n”, ret);

V(m);

}

}

Exercice 4 (Signaux - Implémentation)

Ecrire un programme qui crée un processus fils. Le père et le fils partagent un segment de mémoire. Le père écrit dans l’ordre un opérateur, un opérande 1 et un opérande 2. Le fils devra lire ces informations pour effectuer l’opération (addition, multiplication, soustraction ou division) et afficher le résultat.

Les opérandes 1 et 2 sont des valeurs entières alors que l’opérateur correspond au caractère ‘-‘, ‘+, ‘\*’ ou ‘/’. Le problème qui peut se poser dans ce cas est celui de la cohérence des données car si le fils et le père manipulent simultanément le segment il pourrait y avoir incohérence des données.

Pour cela, on assure la synchronisation des deux processus en utilisant les signaux. Le père écrit dans le segment les données suivantes : opérateur, opérande 1 et opérande 2 puis signale au fils qu’il a produit des informations avant de se terminer. Le fils attend un signal du père avant de lire et de traiter les informations du segment.

Indication: Le fils doit installer un handler associé par exemple au signal SIGUSR1 pour la lecture et le traitement des données.

1- Implémentez la solution correspondante à ce problème.

2- Donnez un imprime-écran de l’exécution de votre code après compilation, pour montrer qu’il s’exécute correctement.

Réponse: Corrigé en classe.

Idée de base :

1- Définir un ensemble de variables globales partagées entre le processus père et le processus fils relatives à opérande 1, opérande 2 et opérateur.

Pour ce faire, vous devez déclarer/établir dans le main un espace mémoire partagé entre le processus père et le processus fils.

2- Construire une fonction traitement (le handler) qui permet de lire ces variables partagées, effectuer l’opération correspondante, et afficher le résultat de cette opération.

3- associer cette fonction au signal SIGUSR1 au niveau du processus fils.

4- implémenter l’envoi de ce signal par le processus père et son exécution par le processus fils.

5-N’oublier pas d’ajouter un wait() au niveau du processus père pour qu’il puisse attendre le processus fils terminer.

TP4 - IPC- Moniteur, Signaux et Pipe

Programming, Inter-Process Communication, Synchronization · lab

Voir tous les documents en programmation

Ecole Nationale des Sciences de l’Informatique A. U. : 2014/2015

Systèmes d’exploitation & Programmation Concurrente II2

TP4 - IPC- Moniteur, Signaux et Pipe ========================================================

Exercice 1 (Moniteur)

1- Ecrire une solution correspondant au problème des lecteurs/rédacteurs traité en classe en utilisant le concept de moniteur. (Le moniteur correspondant doit contenir la déclaration de toutes les procédures et variables nécessaires et l’initialisation de ces dernières).

Monitor LectRed\_Pb {

private int ecr ; //drapeau occupation par un rédacteur

private int nblect; //nbre 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

Publicité

ecr=1;

}

public void FinEcrire () {

ecr=0; //redaction 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;

}

Exercice 2 (Moniteur)

2- Ecrire une solution correspondant au problème des philosophes traité en classe en utilisant le concept de moniteur.

Monitor Philosoph\_Pb {

#define LIBRE=0;

#define OCCUPE=1;

private int Fourchette[5];

private int j;

private condition condManger;

Publicité

/\---------------------\/

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", (int)i,(int)i, ((int)i+1)%5);

}

public void Fini\_de\_Manger(int i){

Fourchette[i]=LIBRE;

Fourchette[(i+1)%5] = LIBRE;

signal(condManger);

printf("Le philosope %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;

}

Exercice 3 (Synchronisation de Processus - Implémentation)

Le but de cet exercice est d’utiliser les modules « ipc.h », « sem.h », et « shm.h » afin de réaliser une synchronisation inter-processus.

Pour celà, vous êtes appelés à implémenter la solution au problème de « gestion de compte bancaire » [traité dans exercice 2 du TP2] en utilisant une synchronisation inter-processus (et non pas une solution multithreadée).

Publicité

Pour cet exercice, on suppose qu’il y a un processus dépositeur (le processus père) et deux processus de retrait (les 2 processus fils). On suppose que montant déposé chaque fois par le processus père est fixe et égal à 100$ et celui retiré par un processus fils est égal à 80$.

Note: Pour vous aider, vous pouvez vous inspirer de l’exemple donné dans le complément du chapitre 4.

1- Implémentez la solution correspondante à ce problème en utilisant une synchronisation inter-processus.

2- Donnez un imprime-écran de votre solution montrant les différentes opérations de dépôt et de retrait bloqué et réussi.

Réponse:

Ici, vu que les montants de dépôt et de retrait ont été fixés à 80 et 100, le problème peut être résolu avec les sémaphores en utilisant les fonctions suivantes :

//Ces variables sont partagées entre les processus

int dep=100 ;

int ret=80 ;

int compte;

void deposit() {

while (1){

P(m); //m semaphore d’exclusion mutuelle (retrait/dépôt) initialisé à 1

compte+=dep;

printf(“Processus père deposits %ld \n”, dep);

V(m);

V(depot); // depot semaphore initialisé à zéro

if((compte mod ret ==0)) V(depot);

sleep (5);

}

}

void withdraw() {

while (1){

Publicité

P(depot);

P(m);

compte = compte - ret;

printf(“Processus fils withdraws %d \n”, ret);

V(m);

}

}

Exercice 4 (Signaux - Implémentation)

Ecrire un programme qui crée un processus fils. Le père et le fils partagent un segment de mémoire. Le père écrit dans l’ordre un opérateur, un opérande 1 et un opérande 2. Le fils devra lire ces informations pour effectuer l’opération (addition, multiplication, soustraction ou division) et afficher le résultat.

Les opérandes 1 et 2 sont des valeurs entières alors que l’opérateur correspond au caractère ‘-‘, ‘+, ‘\*’ ou ‘/’. Le problème qui peut se poser dans ce cas est celui de la cohérence des données car si le fils et le père manipulent simultanément le segment il pourrait y avoir incohérence des données.

Pour cela, on assure la synchronisation des deux processus en utilisant les signaux. Le père écrit dans le segment les données suivantes : opérateur, opérande 1 et opérande 2 puis signale au fils qu’il a produit des informations avant de se terminer. Le fils attend un signal du père avant de lire et de traiter les informations du segment.

Indication: Le fils doit installer un handler associé par exemple au signal SIGUSR1 pour la lecture et le traitement des données.

1- Implémentez la solution correspondante à ce problème.

2- Donnez un imprime-écran de l’exécution de votre code après compilation, pour montrer qu’il s’exécute correctement.

Réponse: Corrigé en classe.

Idée de base :

1- Définir un ensemble de variables globales partagées entre le processus père et le processus fils relatives à opérande 1, opérande 2 et opérateur.

Pour ce faire, vous devez déclarer/établir dans le main un espace mémoire partagé entre le processus père et le processus fils.

2- Construire une fonction traitement (le handler) qui permet de lire ces variables partagées, effectuer l’opération correspondante, et afficher le résultat de cette opération.

3- associer cette fonction au signal SIGUSR1 au niveau du processus fils.

4- implémenter l’envoi de ce signal par le processus père et son exécution par le processus fils.

5-N’oublier pas d’ajouter un wait() au niveau du processus père pour qu’il puisse attendre le processus fils terminer.