Maison  >  Article  >  Opération et maintenance  >  Qu'est-ce qu'une file d'attente de messages ? Utiliser la file d'attente de messages sous Linux

Qu'est-ce qu'une file d'attente de messages ? Utiliser la file d'attente de messages sous Linux

PHP中文网
PHP中文网original
2017-06-21 11:54:402577parcourir
Parlons de la façon d'utiliser les files d'attente de messages pour la communication inter-processus. Les files d'attente de messages présentent de nombreuses similitudes avec les canaux nommés. Pour plus d'informations sur les canaux nommés, veuillez vous référer à mon autre article : Communication inter-processus Linux - utilisation de canaux nommés
1. Qu'est-ce qu'une file d'attente de messages
Files d'attente de messages fournir un moyen d'envoyer un bloc de données d'un processus à un autre. Chaque bloc de données est considéré comme contenant un type, et le processus de réception peut recevoir indépendamment des structures de données contenant différents types. Nous pouvons éviter les problèmes de synchronisation et de blocage des canaux nommés en envoyant des messages. Mais les files d'attente de messages, comme les canaux nommés, ont une limite de longueur maximale pour chaque bloc de données.
Linux utilise les macros MSGMAX et MSGMNB pour limiter la longueur maximale d'un message et la longueur maximale d'une file d'attente.
2. Utilisation des files d'attente de messages sous Linux
Linux fournit une série d'interfaces de fonction de file d'attente de messages qui nous permettent de l'utiliser facilement pour implémenter la communication inter-processus. Son utilisation est similaire aux deux autres mécanismes PIC du System V, à savoir les sémaphores et la mémoire partagée.
1. Fonction msgget
Cette fonction est utilisée pour créer et accéder à une file d'attente de messages. Son prototype est :
[cpp] voir copie brute
imprimer ?
  1. int msgget(key_t, key, int msgflg);

avec d'autres IPC Le mécanisme est la même chose, le programme doit fournir une clé pour nommer une file d'attente de messages spécifique. msgflg est un indicateur d'autorisation, indiquant l'autorisation d'accès à la file d'attente de messages, qui est la même que l'autorisation d'accès au fichier. msgflg peut être associé à un OU avec IPC_CREAT, ce qui signifie créer une file d'attente de messages lorsque la file d'attente de messages nommée par clé n'existe pas. Si la file d'attente de messages nommée par clé existe, l'indicateur IPC_CREAT sera ignoré et seul un identifiant sera renvoyé.
Il renvoie un identifiant (entier non nul) de la file d'attente de messages nommée par clé, et renvoie -1 en cas d'échec
2. .Fonction msgsnd
Cette fonction est utilisée pour ajouter des messages à la file d'attente des messages. Son prototype est :
[cpp] voir copie brute
imprimer ?
  1. int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg

msgid est l'identifiant de la file d'attente de messages renvoyé par la fonction msgget.
msg_ptr est un pointeur vers le message à envoyer, mais la structure de données du message a certaines exigences. La structure du message pointée par le pointeur msg_ptr doit commencer par un membre entier long. variable Structure, la fonction de réception utilisera ce membre pour déterminer le type de message. La structure du message doit donc être définie comme ceci :
[cpp] afficher la copie brute
imprimer ?
  1. struct my_message{

  2. long int message_type; > /* Les données que vous souhaitez transférer*/ 

  3. }; 

  4. msg_sz est la longueur du message pointé par msg_ptr. Notez qu'il s'agit de la longueur du message, et non de la longueur de la structure entière, c'est-à-dire que msg_sz n'inclut pas la longueur de la variable membre du type de message entier.

msgflg est utilisé pour contrôler ce qui se passera lorsque la file d'attente des messages actuelle est pleine ou que le message de la file d'attente atteint une limite à l'échelle du système.
Si l'appel réussit, une copie des données du message sera placée dans la file d'attente des messages et 0 sera renvoyée. S'il échoue, -1 sera renvoyé.
3. Fonction msgrcv
Cette fonction est utilisée pour récupérer les messages d'une file d'attente de messages. Son prototype est
<.>[cpp]
afficher la copie brute
imprimer ?
  1. int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg)

msgid, msg_ptr, msg_st fonctionnent également msgsnd Identique à fonction.
msgtype peut implémenter une simple priorité de réception. Si msgtype est 0, récupère le premier message de la file d'attente. Si sa valeur est supérieure à zéro, le premier message du même type de message sera obtenu. S'il est inférieur à zéro, récupérez le premier message dont le type est égal ou inférieur à la valeur absolue de msgtype.
msgflg est utilisé pour contrôler ce qui se passera lorsqu'il n'y aura pas de message du type correspondant dans la file d'attente à recevoir.
Lorsqu'elle est appelée avec succès, cette fonction renvoie le nombre d'octets placés dans le tampon de réception, le message est copié dans le tampon alloué par l'utilisateur pointé par msg_ptr, puis supprimé du message mettre en file d'attente le message correspondant. Renvoie -1 en cas d'échec
4. Fonction msgctl
Cette fonction est utilisée pour contrôler la file d'attente des messages. Elle est similaire à la fonction shmctl de la mémoire partagée. le prototype est :
[cpp] afficher la copie standard
imprimer ?
  1. int msgctl(int msgid, int command, struct msgid_ds *buf

la commande est l'action à entreprendre, elle peut prendre 3 valeurs,
IPC_STAT : Définissez les données dans la structure msgid_ds sur la valeur actuelle associée de la file d'attente des messages, c'est-à-dire c'est-à-dire, utilisez la valeur associée actuelle de la file d'attente de messages. La valeur associée remplace la valeur de msgid_ds.
IPC_SET : Si le processus dispose des autorisations suffisantes, définissez la valeur actuelle associée de la file d'attente de messages à la valeur donnée dans la structure msgid_ds
IPC_RMID : Supprimez la file d'attente de messages
buf est un pointeur vers la structure msgid_ds, qui pointe vers le mode de file d'attente des messages et la structure des droits d'accès. La structure msgid_ds comprend au moins les membres suivants :
[cpp] view plain copy
print ?
  1. struct msgid_ds

  2. {

  3. uid_t shm_perm.uid

  4. uid_t shm_perm.gid;

  5. mode_t shm_perm.mode

  6. };

Renvoie 0 en cas de succès et -1 en cas d'échec.
Utiliser la file d'attente des messages pour l'inter- communication des processus
Sans nous arrêter, après avoir introduit la définition de la file d'attente de messages et les interfaces disponibles, voyons comment elle permet aux processus de communiquer. Puisque des processus non liés peuvent communiquer, nous écrirons ici deux programmes, msgreceive et msgsned, pour représenter la réception et l'envoi d'informations. Dans des circonstances normales, nous autorisons les deux programmes à créer des messages, mais seul le destinataire supprime le dernier message après l'avoir reçu.
Le fichier source du programme pour recevoir des informations est msgreceive.c et le code source est :
[cpp]
voir la copie brute imprimer ?
  1. #include   

  2. #include   

  3. #include   

  4. #include   

  5. #include   

  6. #include   

  7. struct msg_st  

  8. {  

  9.     long int msg_type;  

  10.     char text[BUFSIZ] ;  

  11. } ;  

  12. int main()  

  13. {  

  14.     int running = 1 ;  

  15.     int msgid = -1;  

  16.     struct msg_st data ;  

  17.     long int msgtype = 0; //注意1  

  18.     //建立消息队列  

  19.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  

  20.     if(msgid == -1)  

  21.     {  

  22.         fprintf(stderr, "msgget a échoué avec l'erreur : %dn", errno);  

  23.         sortie(EXIT_FAILURE);  

  24.     }  

  25.     //从队列中获取消息,直到遇到end消息为止  

  26.     pendant(en cours d'exécution)  

  27.     {  

  28.         if(msgrcv(msgid , (void*)&data, BUFSIZ, msgtype, 0) == -1)  

  29.         {  

  30.             fprintf(stderr, "msgrcv a échoué avec errno : %dn", errno);  

  31.             exit(EXIT_FAILURE);  

  32.         }  

  33.         printf("Vous avez écrit : %sn",data.text);  

  34.         //遇到end结束  

  35.         if(strncmp(data.text, "end", 3) == 0)  

  36.             en cours d'exécution = 0 ;  

  37.     }  

  38.     //删除消息队列  

  39.     if(msgctl(msgid, IPC_RMID, 0) == -1)  

  40.     {  

  41.         fprintf(stderr, "msgctl(IPC_RMID) échec");  

  42.         sortie(EXIT_FAILURE);  

  43.     }  

  44.     sortie(EXIT_SUCCESS);  

  45. }  

发送信息的程序的源文件msgsend.c的源代码为:
 
[cpp] afficher la copie simple
 
 imprimer ?
  1. #include   

  2. #include   

  3. #include   

  4. #include   

  5. #include   

  6. #include   

  7. #define MAX_TEXT 512  

  8. struct msg_st  

  9. {  

  10.     long int msg_type;  

  11.     char text[MAX_TEXT] ;  

  12. } ;  

  13. int main()  

  14. {  

  15.     int running = 1 ;  

  16.     struct msg_st data ;  

  17.     char buffer[BUFSIZ] ;  

  18.     int msgid = -1;  

  19.     //建立消息队列  

  20. msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  

  21.     if(msgid == -1)  

  22.     {  

  23.         fprintf(stderr, "msgget a échoué avec erreur : %dn", errno);  

  24.         sortie(EXIT_FAILURE);  

  25.     }  

  26.     //向消息队列中写消息,直到写入fin  

  27.     pendant que(en cours d'exécution)  

  28.     {  

  29.         //输入数据  

  30.         printf("Entrez un texte : ");  

  31.         fgets(buffer, BUFSIZ, stdin);  

  32.         data.msg_type = 1;    //注意2  

  33.         strcpy(data.text, buffer);  

  34.         //向队列发送数据  

  35.         if(msgsnd(msgid, (void *)&data, MAX_TEXT, 0) == -1)  

  36.         {  

  37.             fprintf(stderr, "msgsnd failedn");  

  38.             exit(EXIT_FAILURE);  

  39.         }  

  40.         //输入end结束输入  

  41.         if(strncmp(buffer, "end", 3) == 0)  

  42.              running = 0;  

  43.          sommeil(1);  

  44.     }  

  45.     sortie(EXIT_SUCCESS);  

  46. }  

运行结果如下:
4. Exemple d'analyse - Type de message
Ici, nous expliquons principalement quel est le type de message. Faites attention à la variable msgtype définie dans la fonction principale du fichier msgreceive.c (annotée comme note 1). Elle est utilisée comme valeur du paramètre de type d'information reçu du. msgrcv, et sa valeur est 0 , indiquant l'obtention du premier message disponible dans la file d'attente. Jetons un coup d'œil à l'instruction data.msg_type = 1 dans la boucle while du fichier msgsend.c (note 2). Elle est utilisée pour définir le type d'information des informations envoyées, c'est-à-dire que le type d'informations envoyées est 1. . Ainsi le programme msgceive peut recevoir les informations envoyées par le programme msgsend.
Que se passera-t-il si la note 1, c'est-à-dire que l'instruction dans la fonction principale du fichier msgreceive.c passe de long int msgtype = 0 à long int msgtype = 2 ; , msgreceive ne pourra pas recevoir les informations envoyées par le programme msgsend. Car lors de l'appel de la fonction msgrcv, si msgtype (le quatrième paramètre) est supérieur à zéro, seul le premier message du même type de message sera obtenu. Après modification, le type de message obtenu est 2, et le type de message envoyé par msgsend est. 1. Il ne peut donc pas être reçu par le programme msgreceive. Recompilez le fichier msgreceive.c et exécutez-le à nouveau. Le résultat est le suivant :

Nous pouvons voir. que msgreceive Aucune information ou sortie n'est reçue, et lorsque les entrées de msgsend se terminent, msgreceive ne se termine pas Grâce à la commande jobs, nous pouvons voir qu'il s'exécute toujours en arrière-plan.
5. Comparaison des files d'attente de messages et des canaux nommés
Les files d'attente de messages et les canaux nommés présentent de nombreuses similitudes. avec lesquels communique peuvent être des processus sans rapport, et ils transmettent tous des données en envoyant et en recevant. Dans un canal nommé, write est utilisé pour envoyer des données et read pour recevoir des données. Dans une file d'attente de messages, msgsnd est utilisé pour envoyer des données et msgrcv est utilisé pour recevoir des données. Et ils ont une limite de longueur maximale pour chaque donnée.
Par rapport aux canaux nommés, les avantages des files d'attente de messages sont les suivants : 1. Les files d'attente de messages peuvent également exister indépendamment des processus d'envoi et de réception, éliminant ainsi le besoin de synchroniser l'ouverture et la fermeture. des difficultés de canalisations nommées qui peuvent survenir. 2. Dans le même temps, en envoyant des messages, vous pouvez également éviter les problèmes de synchronisation et de blocage des canaux nommés, et le processus lui-même n'a pas besoin de fournir des méthodes de synchronisation. 3. Le programme récepteur peut recevoir des données de manière sélective via des types de messages, au lieu de recevoir uniquement des données par défaut comme dans les canaux nommés.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Comment configurer NTP ?Article suivant:Comment configurer NTP ?