IPC - file d'attente de messages

0. Qu'est-ce qu'une file d'attente de messages

La file d'attente de messages peut être considérée comme une liste de messages. Les threads peuvent placer des messages dans la file d'attente de messages ou retirer des messages. Chaque message est un enregistrement, prioritaire par l'expéditeur. Un processus n'a pas besoin d'attendre qu'un message arrive dans la file d'attente avant d'écrire un message dans une file d'attente de messages (c'est le contraire des tubes et des FIFO).

La file d'attente de messages a une persistance avec le noyau, c'est-à-dire qu'avant le redémarrage du noyau, la file d'attente de messages existera toujours indépendamment du fait que le processus d'envoi ou de récupération de message se termine.

Il existe deux types de files d'attente de messages, la file d'attente de messages Posix et la file d'attente de messages System V. L'exemple suivant est l'utilisation de la file d'attente de messages Posix.

1. Ouvrez (ou créez), fermez la file d'attente des messages

// 1.c
#include<stdio.h>
#include<mqueue.h>

#define  FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
int main(int argc, char* argv[]) 
{
    int     flag;
    mqd_t   mdq;
    flag = O_RDWR | O_CREAT;
    if (argc < 2) {
        printf("Please input mqueue name!\n");
    }
    // NULL 表示采用默认属性
    mdq = mq_open(argv[1], flag, FILE_MODE, NULL);
    return 0;
}

Ce qui précède est une routine pour créer une file d'attente de messages. Utilisez la commande suivante pour compiler et obtenir le fichier exécutable a.out

gcc -g 1.c -Wall -lrt

Exécutez la commande suivante, vous pouvez obtenir une file d'attente de messages nommée temp.1234, qui est stockée dans / dev / mqueue

./a.out /temp.1234
[root@localhost IPC]#  ll /dev/mqueue/
total 0
-rw-r--r--. 1 root root 80 Nov  9 06:59 temp.1234

Notez que le nom de la file d'attente de messages doit commencer par un «/» pour être créé avec succès.

2. Supprimez la file d'attente des messages

Pour supprimer la file d'attente de messages, utilisez la fonction mq_unlink.

// 2.c
#include<stdio.h>
#include<mqueue.h>

int main(int argc, char* argv[]) 
{
    if (argc < 2) {
        printf("Please input mqueue name!\n");
    }
    int ret = mq_unlink(argv[1]);
    printf("%d\n", ret);
    return 0;
}

Compiler

gcc -g 2.c -Wall -lrt

effectué

./a.out /temp.1234

Après l'exécution, vous pouvez voir que la file d'attente de messages qui vient d'être créée a été supprimée.

[root@localhost IPC]# ll /dev/mqueue/
total 0

3. obtenir / définir les propriétés de la file d'attente de messages

Chaque file d'attente de messages a quatre attributs et la fonction mq_getattr renvoie tous ces attributs.

struct mq_attr {
    long mq_flags;
    long mq_maxmsg; //消息队列上最多可以存储的消息数目
    long mq_msgsize; //一条消息最多可以容纳多少字节
    long mq_curmsgs; //当前队列中存储的消息数量
};
// 3.c
#include<stdio.h>
#include<mqueue.h>

int main(int argc, char* argv[]) 
{
    mqd_t           mqd;
    struct mq_attr  attr;

    if (argc < 2) {
        printf("Please input mqueue name!\n");
    }
    mqd = mq_open(argv[1], O_RDONLY);

    mq_getattr(mqd, &attr);
    printf("max msgs = %ld\nmax bytes/msg = %ld\ncurrently on queue = %ld\n", 
            attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
    mq_close(mqd);
    return 0;
}

Compilez et exécutez, affichez les propriétés de la file d'attente de messages que nous venons de créer

gcc -g 3.c -Wall -lrt
./a.out /temp.1234
max msgs = 10
max bytes/msg = 8192
currently on queue = 0

Vous pouvez voir que la file d'attente de messages que nous avons créée peut contenir jusqu'à 10 messages, chaque message a un maximum de 8192 octets et il n'y a aucun message dans la file d'attente actuelle.

La fonction mq_setattr définit les attributs de la file d'attente, mais n'utilise que le champ mq_flags de la structure mq_attr pour définir ou effacer le bit d'indicateur non bloquant. Les trois autres membres de cette structure sont ignorés.

Si vous souhaitez définir le nombre maximum de messages et le nombre maximum d'octets par message, vous devez les spécifier lors de la création de la file d'attente.

4. Créez une file d'attente avec les attributs spécifiés

Dans l'exemple précédent, le nombre maximal de messages qu'une file d'attente créée avec les attributs par défaut peut contenir est de 10 et chaque message a un maximum de 8 192 octets. Maintenant, nous essayons de créer une file d'attente avec les attributs que nous spécifions.

// 4.c
#include<stdio.h>
#include<mqueue.h>

#define  FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

struct mq_attr attr;
int main(int argc, char* argv[]) 
{
    int     flag;
    mqd_t   mdq;
    flag = O_RDWR | O_CREAT;
    if (argc < 2) {
        printf("Please input mqueue name!\n");
        return -1;
    }
    attr.mq_maxmsg = 20;
    attr.mq_msgsize = 4096;
    mdq = mq_open(argv[1], flag, FILE_MODE, &attr);
    mq_close(mdq);
    return 0;
}

Dans cet exemple, nous définissons le nombre maximum de messages sur 20, et chaque message a un maximum de 4096 octets.
Compilez et exécutez et vérifiez les propriétés

max msgs = 20
max bytes/msg = 4096
currently on queue = 0

Comme vous pouvez le voir, cette fois, nous avons créé une file d'attente de messages différente.

5. fonction mq_send / mq_receive

Ces deux fonctions sont utilisées pour ajouter et supprimer des messages dans une file d'attente. Chaque message a une priorité, mq_receive renvoie toujours le message le plus ancien avec la priorité la plus élevée dans la file d'attente, et la priorité peut être renvoyée avec le contenu et la longueur du message.

envoyer

// send
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<mqueue.h>

int main(int argc, char* argv[]) 
{
    int     priorty;
    mqd_t   mqd;

    if (argc != 4) {
        printf("usage: send <name> <message> <priorty>n");
        return -1;
    }
    priorty = atoi(argv[3]); 
    mqd = mq_open(argv[1], O_WRONLY);
    int ret = mq_send(mqd, argv[2], strlen(argv[2]), priorty);
    if (ret != 0) {
        printf("send message error!\n");
    }
    mq_close(mqd);
    return 0;
}

recevoir

// receive
#include<stdio.h>
#include<stdlib.h>
#include<mqueue.h>

struct mq_attr attr;
int main(int argc, char* argv[]) 
{
    unsigned int     priorty, cnt;
    mqd_t   mqd;
    void*   buff;

    if (argc != 2) {
        printf("usage: mqrece <name> \n");
        return -1;
    }

    mqd = mq_open(argv[1], O_RDONLY);
    mq_getattr(mqd, &attr);
    printf("size = %ld\n", attr.mq_msgsize);
    buff = malloc(attr.mq_msgsize);
    cnt = mq_receive(mqd, buff, attr.mq_msgsize, &priorty);

    printf("received %d bytes, priority = %u\n", cnt, priorty);
    printf("message = %s\n", (char*)buff);
    mq_close(mqd);
    return 0;
}

6. Limite de la file d'attente des messages

L'implémentation de la file d'attente de messages définit deux restrictions:

  • MQ_OPEN_MAX Le nombre maximum de files d'attente de messages qu'un processus peut ouvrir en même temps (Posix nécessite un minimum de 8)
  • MQ_PRIO_MAX La valeur de priorité maximale de tout message plus 1 (Posix nécessite au moins 32)

Ces deux valeurs sont généralement définies dans <unistd.h> et peuvent être obtenues via la fonction sysconf

#include<stdio.h>
#include<unistd.h>

int main() 
{
    printf("MQ_OPEN_MAX = %ld\nMQ_PRIO_MAX = %ld\n", sysconf(_SC_MQ_OPEN_MAX), sysconf(_SC_MQ_PRIO_MAX));
    return 0;
}

Le résultat de l'exécution sous Linux est

MQ_OPEN_MAX = -1
MQ_PRIO_MAX = 32768

-1 signifie qu'il n'y a pas de limite à la quantité

Je suppose que tu aimes

Origine blog.csdn.net/ww1473345713/article/details/102992076
conseillé
Classement