TP de système #4 : étude des fonctionnalités IPC
Au cours, de ce TP, nous allons utiliser les 3 fonctionnalités IPC proposées par Unix que sont :
Eût égard à la quantité de travail à fournir, ce TP n'est pas destiné à être terminé en une seule séance, mais plutôt à y être débroussaillé. Aussi, je vous conseille de vous frotter à toutes les questions afin de poser les questions nécessaires à son accomplissement.
Nous allons réaliser une structure de communication connue sous le nom de Tableau Noir. Lorsque divers processus souhaitent communiquer, ils utilisent un espace commun placé en mémoire partagée : le tableau noir où sont placées les informations à diffuser. Il existe plusieurs variantes de cette structure, celle que nous allons utiliser à la particularité d'utiliser les 3 fonctionnalités IPC (pour le caractère pédagogique).
Supposons que le processus A souhaite partager des données avec les processus B, C et D. Plutôt que de leur envoyer à chacun un message contenant toutes les informations (qui peuvent être d'une taille conséquente), il va créer un segment de mémoire partagée, y placer les données, et envoyer à chacun des destinataires des informations un message de longueur fixe leur indiquant où trouver les informations en mémoire partagée.
En outre, on suppose que le processus émetteur A ne pourra reprendre son exécution avant que les destinataires (B, C et D dans ce cas) n'aient pris connaissance des données. Afin de réaliser cette synchronisation, le processus A va créer un sémaphore et effectuer une opération P dont le cardinal sera le nombre de clients. Chacun des clients devra alors effectuer une opération V de cardinal 1 pour réactiver l'émetteur.
Un message devra donc contenir les informations suivantes :
| Description de l'information | Type de données |
|---|---|
| Type du message (requis par la primitive d'envoie msgsnd) | long |
| Identificateur du segment de mémoire partagée | int |
| Identificateur du sémaphore de réactivation de l'émetteur | int |
| Taille (en octets) des informations | int |
| Description des données | Chaîne de 256 caractères au format ASCIIZ |
Bien entendu, vous aurez intérêt à déclarer une struct destinée à recevoir un tel message. Sa taille est à déterminer à l'aide de l'opérateur sizeof.
Chacun des destinataires du message pourra alors traiter les données qui lui sont proposées en attachant le segment de mémoire partagée dont l'identificateur lui est passé par message. Une fois les données lues, chaque destinataire devra effectuer une opération V sur le sémaphore de contrôle afin de libérer le processus A.
Tout ceci est bien beau, mais vous vous posez sans doute trois questions :
Les sections suivantes vont proposer une solution pour chacun des deux premiers problèmes dans un cas simplifié :
Nous avons choisi d'utiliser un fichier qui contiendra la liste des identificateurs des boîtes aux lettres des clients. Il est plus pratique d'utiliser une liste d'identificateurs qu'une liste de clefs car vous n'aurez pas à faire une opération msgget pour récuper l'identificateur à partir de la clef.
Ce système est très simple mais comporte plusieurs défauts.
Nous avons choisi de passer la clef associée à chaque processus sur la ligne de commande. Si nous reprenons l'information ci-dessus, chaque processus devra prendre sur sa ligne de commande à la fois la clef de création de ses fonctionnalités propres et le nom du fichier destiné à recevoir la liste des clients
On peut imaginer plusieurs systèmes pour résoudre en une seule fois les 2 problèmes précédents. En effet, rappelons-nous qu'il existe une fonction nommée ftok qui permet de créer une clef à partir d'un nom de fichier existant. Si chaque client crée un fichier dans un espace commun (un sous répertoire du /tmp par exemple) il sera alors possible d'obtenir à la fois une clef, et, en utilisant des noms de fichiers normalisés, la liste des boîtes à lettres.
On supprime ainsi le problème du fichier et celui du passage des clefs sur la ligne de commande. Reste que les différents processus doivent connaître le répertoire de base qui peut être passé sur la ligne de commande. Afin que l'émetteur n'oublie personne, il faudra encore lancer les clients avant l'émetteur.
On peut aller encore plus loin en imaginant des hiérarchies complexes de sous répertoires spécifiant chacun le type d'IPC et le propriétaire. On obtient alors le système utilisé par OS/2.
Afin de simplifier, nous allons utiliser un coordinateur sous la forme d'un script shell. Il sera chargé de :
Ses paramètres seront les suivants :
Afin de simplifier le TP, nous donnons ici la séquence opératoire de chaque type de processus.
La séquence d'opérations pour le processus A est représentée par la figure suivante :
Chaque processus destinataire, accomplissant quand à lui les opérations suivantes :
Vous devez créer les 2 types de processus : émetteur et client ainsi que le script de coordination.
Bon, voici un lien vers la solution !