TP8 : Utilisation des IPC Unix

publicité
TP8 : Utilisation des IPC Unix
1
Partage de zone mémoire
Commencez par lire cette documentation sur les IPC Unix1 et faites tourner l’exemple proposé. Nous allons
utiliser la mémoire partagée IPC pour inplanter un petit exemple de producteur/consommateur. La zone partagée
pourrait être du type suivant :
struct {
int nb_chars_prod;
int nb_chars_conso;
char data[MAX];
int fin;
} ...
/*
/*
/*
/*
Nb de caractères produits */
Nb de caractères consommés */
tampon */
signal de fin d’entrée */
Le nombre de caractères disponibles dans le tampon est égal à (nb chars prod-nb chars conso). Le consommateur peut consommer si, et seulement si, (nb chars prod > nb chars conso). Le producteur peut produire
ssi ((nb chars prod-nb chars conso) < MAX). Je vous propose de suivre les étapes ci-dessous :
1. Le producteur et le consommateur sont des processus différents et des programmes différents. Le producteur lit des caractères au clavier et les place dans le tampon. Le consommateur les récupère et les affiche.
Ces deux acteurs appliquent la méthode de l’attente active pour se synchroniser.
2. Faites en sorte que la zone partagée soit créée et initialisée par le producteur. Si le consommateur est plus
rapide, il doit attendre que la zone partagée soit disponible.
3. Prenez soin de ralentir le producteur et le consommateur pour tester tous les cas de figure.
4. La fin de la lecture au clavier est indiquée au consommateur par la mise à un du drapeau fin. Ce dernier
a la charge de supprimer la ressource partagée avant de se terminer.
2
Les sémaphores à messages
Refaites le même exercice mais en remplaçant la mémoire partagée par un envoi de message entre le producteur
et le consommateur. Faites en sorte de ne pas envoyer un caractère dans chaque message, mais plutôt une ligne.
3
Montage de fichiers en mémoire
La fonction mmap permet de projeter un fichier en mémoire (plus de précisions avec man mmap). Voila un petit
exemple :
1
ref:dil-doc-IPC
1
#include
#include
#include
#include
#include
#include
<sys/types.h>
<unistd.h>
<sys/types.h>
<sys/stat.h>
<fcntl.h>
<sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
void creer_fichier(int taille)
{
int i;
FILE *f = fopen("data", "w");
for(i=1; i<taille; i++) fputc(’A’, f);
fputc(’\n’, f);
fclose(f);
}
int main()
{
int file;
char* zone;
int i;
int taille = 60;
/* creation du fichier pour l’exemple */
creer_fichier(taille);
/* ouverture en utilisant les fonctions UNIX */
file = open("data", O_RDWR, 0700);
if (file < 0) {
perror("open");
return (EXIT_FAILURE);
}
/* montage en memoire */
zone = mmap(NULL, taille, PROT_READ, MAP_SHARED, file, 0);
if (zone == NULL) {
perror("mmap");
return (EXIT_FAILURE);
}
/* utilisation */
printf("Affichage du contenu\n");
for(i=0; (i<taille); i++) putchar(zone[i]);
return (EXIT_SUCCESS);
}
1. Exécutez l’exemple et étudiez son fonctionnement.
2. Modifiez un des caractères en vérifiant la mise à jour automatique du fichier sur disque.
3. Alors que votre processus à déjà projeté le fichier (freinez le avec un getchar()), modifiez le fichier d’origine
et vérifiez que la modification est bien reportée dans la version projetée.
2
Téléchargement