Nous présentons à présent un second outil de communication entre processus Unix : les files de messages ou MSQ.

4 Définition et propriétés des MSQ

 
 
Les files de messages UNIX constitue un autre mécanisme de communication entre processus UNIX placés sur une même machine. À la différence du mécanisme des tubes, le mécanisme des files de message est externe au système de gestion de fichiers du système UNIX. Le système gère une table spécifique pour cet outil, qui est identifié par une clé de type key_t. Cette clé est une valeur numérique et tout processus ayant connaissance de la clef peut utiliser la file de messages pour envoyer ou recevoir des messages. On voit donc qu'à la différence des tubes, la file de message peut être utilisée par des processus non nécessairement affiliés entre eux. La file de message constitue l'implémentation UNIX du concept de boîtes aux lettres. Il offre deux propriétés : la préservation de la limite des messages ce qui est différent des tubes, et la possibilité de multiplexage c'est-à-dire qu'une seule file peut servir pour plusieurs destinataires. Les messages postés dans une file de messages sont obligatoirement constitués de deux parties:
  • Un type qui est un entier long. Ce type est utile pour réaliser le multiplexage.
  • Les données
Un exemple de messages
 
 
     struct message {
 
 
                    long mtype; -- le type
 
 
                    float n1 ;
 
 
                    int tab[4];
 
 
                   }
 
 
Définition : File de messages (MSQ)
Une file de messages est un outil de communication entre processus Unix non nécessairement affiliés placés sur une même machine qui implémente le concept de boîtes aux lettres. Une file de message ou MSQ est identifiée par une clé.

5 Les primitives associées aux MSQ

5.1 Création et accès à une MSQ

 
 
La primitive MSGGET permet à un processus soit de créer une nouvelle file de messages, soit de récupérer une file de messages existantes afin de l'utiliser.
Définition : Primitive msgget
int msgid = msgget (key_t cle, int option) : permet de créer une nouvelle file de messages ou de récupérer une file de messages existante. 
 
 
Le premier paramètre de la primitive, clé, permet de spécifier l'identifiant de la MSQ. Le second paramètre, option, est une combinaison des constantes IPC_CREAT, IPC_EXCL et des droits d'accès associés à la file. La primitive en cas de succès retourne un identifiant interne au programme msgid. Plus précisément, la création d'une file est obtenue grâce aux combinaisons suivantes : 
  • Positionnement de IPC_CREAT et de IPC_EXCL : création d'une nouvelle file de messages avec les droits spécifiés dans option, à condition que la file ayant pour référence clé n'existe pas déjà. Sinon, il y a erreur
  • Positionnement de IPC_CREAT seul: création d'une nouvelle file de messages avec les droits spécifiés dans option, si celle-ci n'existe pas
 
 
La récupération d'une file existante s'obtient en mettant les options à 0.
CREATION D'UNE FILE de clé 17 en lecture écriture pour tous
 
 
#define CLE 17
 
 
int msqid;
 
 
msqid = msgget (CLE, IPC_CREAT | IPC_EXCL | 0666);
 
 
 
 
RECUPERATION D'UNE FILE de clé 17
 
 
#define CLE 17
 
 
int msqid;
 
 
msqid = msgget (CLE,0);
 
 

5.2 Envoi d'un message dans la file de messages

 
 
La primitive msgsnd permet l'envoi d'un message dans une file de messages.
Définition : Primitive msgsnd
int msgsnd (int msgid, struct message *buf, int lg, int option) : envoi du message buf de taille lg octets dans la MSQ d'identifiant msgid. Les options permettent de rendre l'envoi non bloquant si la file est pleine.

5.3 Réception d'un message depuis la file de messages

 
 
La primitive msgrcv permet de recevoir un message depuis une file de messages. C'est à ce niveau qu'intervient le multiplexage dont nous avons parlé précédemment, c'est-à-dire que le récepteur peut désigner parmi les messages présents dans le file, un message qu'il souhaite plus spécifiquement recevoir. 
Définition : Primitive msgrcv
int msgrcv (int msgid, struct message *buf, int lg, long montre, int option) : réception du message buf de taille lg octets dans la MSQ d'identifiant msgid. Le paramètre montre spécifie le type de message à extraire. Les options permettent de rendre la réception non bloquante si la file ne contient pas de message avec le type attendu.
 
 
Le multiplexage utilise le paramètre type des messages. Les interprétations possibles du paramètre montre spécifié dans la primitive msgrcv sont les suivantes :
  • Si montre > 0 alors le message le plus vieux dont le type est égal à montre est extrait.
  • Si montre = 0 alors le message le plus vieux, quel que soit son type,, est extrait.
  • Si montre < 0, alors le message le plus vieux de type le plus petit inférieur ou égal à |montre| est extrait.

5.4 Destruction d'une file de messages

 
 
La primitive msgctl permet l'accès et la modification des informations contenues dans la table des files de messages gérée par le système. Plus précisément, utilisée avec comme opération la valeur IPC_RMID, elle permet la destruction de la file de message dont l'identifiant est passé en paramètre.
Définition : Primitive msgctl
int msgctl (int msgid, int op, struct msgid_ds *buf) : accès et modification des informations contenues dans la table des files de messages gérée par le système int msgctl (msgid, IPC_RMID, NULL) : destruction de la file de message identifiée par msgid.

6 Un exemple de programmation avec les MSQ.

Processus 1 : crée la file et envoi un message dans cette file
 
 
/* création d'une MSQ et envoi message*/
 
 
#include <sys/types;h>
 
 
#include <ipc.h>
 
 
#include <msqg.h>
 
 
#define CLE 17
 
 
struct msgbuf msgp;
 
 
char *msg="ceci est un message";
 
 
 
 
main()
 
 
{ int msqid; /* identificateur msq */
 
 
msqid = msgget((key_t)CLE,0666| IPC_CREAT | IPC_EXCL);/* creation msq */
 
 
msgp.mtype=12; /* le type */
 
 
strcpy(msgp.mtext,msg); /* le message */
 
 
msgsnd(msqid, &msgp, strlen(msg), 0) /* envoi message */
 
 
exit(0); }
 
 
 
 
Processus 2 : reçoit un message depuis la file 17 puis la détruit.
 
 
 
 
/* lecture message et destruction msq*/
 
 
#include <sys/types;h>
 
 
#include <ipc.h>
 
 
#include <msqg.h>
 
 
#define CLE 17
 
 
struct msgbuf msgp;
 
 
 
 
main()
 
 
{ int msqid; int x;
 
 
msqid = msgget((key_t)CLE, 0);       /* récup msqid */
 
 
x = msgrcv (msqid, &msgp, 19, (long)12, 0) /* lecture type 12*/
 
 
msgp.text[x] = 0;
 
 
printf ("message lu %s÷n",msgp.mtext);
 
 
msgctl(msqid,IPC_RMID, NULL); /* destruction */
 
 
exit(0); }
 
 
Outils de communication centralisés entre processus Les tubes anomymes Les files de message ou MSQ