POSIX message queues

 

1. What is the message queues are?

(1) it is an IPC message queue way.

(2) stored in the kernel, implemented by VFS, mounted under the / dev / mqeueue.

(3) Data structure: with a priority queue

 

2. Comparison of the message queue and a duct

(1) call is similar to the pipe, similar to a mail message queue.

(2) a pipe communication, the sender and receiver must both open pipe or communication failure or meaningless.

          If the pipe is closed in the data pipeline will be lost.

(3) message queue, the sender and the recipient can not read the message queue at the same time,

           If the message queue structure is closed, the message queue file is still saved data.

 

Compared with the message queue 3.POSIX SystemV

POSIX updated, easier and more powerful.

(1) reading of the message queue Posix highest priority always returns the first message, the read System V message queue may return any specified priority message.

(2) when an empty queue to place a message, the message queue allows the Posix generates a signal to start a thread or similar mechanism System V message queues is not provided.

 

4.api learning

(0) link use POSIX message queues -lrt

(1) create a message queue file

Use API:

       mqd_t mq_open(const char *name, int oflag);
       mqd_t mq_open(const char *name, int oflag, mode_t mode,
                     struct mq_attr *attr);
void creat_mq(const char *mq_name)
{
    int oflag;
    mode_t mode;
    mqd_t mqd = -1;

    oflag = O_RDWR | O_CREAT | O_EXCL;
    mode = S_IRUSR | S_IWUSR | S_IRGRP  | S_IROTH ;

    mqd = mq_open(mq_name, oflag, mode, NULL);    // 创建的mq在/dev/mqueue下
    if (mqd == -1) {
        perror("mq_open");
        goto __end;
    }

__end:
    if (!mqd) {
        printf("mq_close");
        mq_close(mqd);
    }
}

(3) delete the message queue file

Using the API

int mq_unlink(const char *name);
void unlink_mq(const char *mq_name)
{
    if (mq_unlink(mq_name) < 0) 
        perror("mq_unlink");
}

(4) Set the Message Queue properties

       int mq_getattr(mqd_t mqdes, struct mq_attr *attr);

       int mq_setattr(mqd_t mqdes, const struct mq_attr *newattr,
                        struct mq_attr *oldattr);

Related attributes:

           struct mq_attr {
               long mq_flags;       /* Flags: 0 or O_NONBLOCK */
               long mq_maxmsg;      /* Max. number of messages on queue */
               long mq_msgsize;     /* Max. message size (bytes) */
               long mq_curmsgs;     /* # of messages currently in queue */
           };

(5) messaging

Using the API

      int mq_send(mqd_t mqdes, const char *msg_ptr,
                     size_t msg_len, unsigned int msg_prio);
     ssize_t mq_receive(mqd_t mqdes, char *msg_ptr,
                          size_t msg_len, unsigned int *msg_prio);
mqd_t open_mq(const char *name, int oflag)
{
    mqd_t mqd = -1;

    mqd = mq_open(name, O_RDWR);
    if (mqd < 0) 
        perror("mq_open");

    return mqd;
}

int send_mq(mqd_t mqd, const char *buf, int len, int priority)
{
    int n;

    n = mq_send(mqd, buf, len , priority);
    if (n < 0 || n != len) {
        perror("mq_send");
    }

    return n;
}

int recv_mq(mqd_t mqd, char *buf)
{
    int n;
    struct mq_attr attr;

    if (mq_getattr(mqd, &attr) < 0) 
        perror("mq_getattr");
    n = mq_receive(mqd, buf, attr.mq_msgsize, NULL);    // 需要使用 msg_len
    if (n < 0 || n != attr.mq_msgsize) 
        perror("mq_receive");

    return n;
}

void test_send_recv()
{
    const char *mq_file = MQ_FILE;
    char buf[100];
    mqd_t mqd = -1;
    int send_number, recv_number, nbytes, priority;

    if ((mqd = open_mq(mq_file, O_RDWR)) < 0)
        goto __end;
    snprintf(buf, sizeof(buf), "hello world\n");
    send_number = 3;
    priority = 20;
    while (send_number--) 
        nbytes = send_mq(mqd, buf, strlen(buf), priority);

    bzero(buf, sizeof(buf));
    recv_number = 4;                // 默认阻塞读
    while (recv_number--) {        
        recv_mq(mqd, buf);
        printf("recv : %s\n", buf);
    }

__end:
    if (mqd != -1)
        close(mqd);
}

It should be noted, accepting msg, msg_len obtained from the use of msg files that mqd_attr.mq_msgsize.

 

Guess you like

Origin www.cnblogs.com/yangxinrui/p/11229443.html