Université Pierre et Marie Curie Master 2016 2017
PR : Travaux sur Machine 6. Introduction à la communication inter-processus (IPC)

Cette première séance consacrée aux segments de mémoire partagée et aux files de messages évite les accès concurrents à ces nouvelles ressources afin d’en maîtriser l’écriture de base. Les premiers exercices sont des réécritures avec ces outils de celui des remontées de valeurs de la séance Fichiers et Processus, sans écrire dans un fichier. Vous disposez de l’annexe "remonte.c" qui reprend la fonction main de cette séance, mais plusieurs instructions sont remplacées par des appels à des macros C. Pour chacun des exercices, il vous est demandé d’écrire un fichier C réduit à quelques directives include et #define, ces dernières définissant les macros référencées dans l’annexe. La dernière ligne de chacun de ces fichiers sera simplement #include "remonte.c", fichier que vous placerez dans un sous-répertoire nommé include où le Makefile fourni s’attend à le trouver. Cette technique permettra de produire un code différent à partir du même programme principal. Vous pourrez utiliser l’option -E du compilateur C pour examiner la macro-expansion. A noter que les paramètres d’une macro ne sont pas tous forcément utiles : obtenir une unique fonction main a imposé d’appeler chaque macro avec les arguments nécessaires à au moins une version, non à toutes.

Les deux derniers exercices sont des variantes où ce n’est plus le processus principal mais les processus fils qui effectuent des sommes de valeurs aléatoires, en utilisant des files de messages.

Remarque 1 : Selon les plates-formes, vous aurez peut-être besoin d’ajouter dans le Makefile l’option -lrt pour l’édition de liens.

Remarque 2 : les files de messages et les segments de mémoire partagée créés à chaque exécution doivent impérativement être détruits en fin de programme sinon des comportements incohérents s’ensuivront, liés à des variables dont les valeurs sont restées en mémoire après la terminaison du programme précédent. Pour vérifier ce qu’il en est, utilisez la commande ipcs et ses congénères cités dans le manuel.



1 Remontée par partage de mémoire

Définir les macros nécessaires au canevas fourni pour que les valeurs soient remontées au processus principal via un segment de mémoire partagée,disponible en POSIX à l’aide des fonctions C shm_open, shm_unlink, mmap, munmap et ftruncate.

Exemple d'appel :
$PWD/bin/remonte_posix_partagee 4
Fichier à créer : src/remonte_posix_partagee.c

2 Remontée par partage System V (facultatif)

Si vous connaissez les équivalents System V des fonctions POSIX sur la mémoire partagée, définir les macros pour ce même canevas dans ce contexte. Les fonctions sont shmget, shmat et shmctl, et afin d’obtenir une clé spécifique, vous appliquerez la fonction ftok par exemple sur le nom du programme et les 7 bits de poids faible du numéro de processus, en veillant à ce que ce ne soit pas 0. Vous n’oublierez pas de remplacer

#define _XOPEN_SOURCE 700

par

#define _SVID_SOURCE 1

en début de fichier.

Exemple d'appel :
$PWD/bin/remonte_sv_partagee 4
Fichier à créer : src/remonte_sv_partagee.c

3 Remontée par file de messages

Adaptez l’exercice précédent cette fois à l’utilisation d’une file de messages pour envoyer chaque valeur aléatoire. Vous utiliserez les fonctions C mentionnées dans le cours. Il faudra parfois définir une variable supplémentaire dans les macros, et à l’inverse certaines macros ne produiront rien, file et mémoire partagée étant des techniques sensiblement différentes. Des avertissements de variables inutilisées pourront en résulter à la compilation.

Exemple d'appel :
$PWD/bin/remonte_ipc 4
Fichier à créer : src/remonte_ipc.c

4 Serveur de valeurs aléatoires à files multiples

On souhaite à présent que chaque processus soit associé à une file de messages MQi, où i est le numéro d’ordre de création du processus fils : 0 < i < N-1. Le programme principal est associé à la file MQN. Il y a donc en tout N+1 files de messages.

Cette fois-ci la valeur aléatoire générée par chaque processus fils, notée max_msg_i (1 <= max_msg_i <= N), représente le nombre de messages que le processus fils veut recevoir de son père. Une fois générée, chaque fils envoie cette valeur à son père par le biais de la file de messages associée au processus principal. Chaque processus fils attend ensuite sur sa propre file de messages que son père lui renvoie max_msg_i messages.

Dans ces messages, le processus père insère à chaque fois une valeur tirée aléatoirement entre 0 et 100. Lorsque tous les messages ont été extraits de sa file, chaque processus fils fait la somme des valeurs reçues et affiche le résultat.

Exemple d'appel :
bin/multi_remonte 4
Fichier à créer : src/multi_remonte.c

5 Serveur de valeurs aléatoires à file unique

Reprenez le programme de l’exercice précédent en remplaçant les files par des segments de mémoire partagée, sauf la file MQN qui est conservée. Le père signalera à chacun de ses fils qu’il a mis les messages dans le segment de mémoire partagée en lui envoyant un signal.

Exemple d'appel :
bin/multi_remonte_file_unique 4
Fichier à créer : src/multi_remonte_file_unique.c

6 Annexes


makefile

remonte.c
Format de l'envoi : src/remonte_ipc.c
Répertoires autorisés : src/remonte_partagee.c src/multi_remonte.c src/multi_remonte_file_unique.c