Message Queues

Linux has two different Message Queues implementation, XSI Message Queue, POSIX Message Queue.

The interface of XSI Message Queue.

#include <sys/msg.h>

int msgget(key_t key, int flag);

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

int msgctl(int msqid, int cmd, struct msqid_ds *buf );

The interface of POSIX Message Queue.

The POSIX message queue need Linux version > 2.6.6 and glibc version > 2.3.4

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <mqueue.h>

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);

The demo of create a XSI message queue and print status information.

#include "apue.h"

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

#define PATH    "/workspace/c/apue/mq_x"
#define ID      1234

void
mq_status(void) {
    int msgid;
    key_t key;
    struct msqid_ds msg_buf;

    key = ftok(PATH, ID);
    if (key == -1) {
        err_sys("ftok failed");
    }

    msgid = msgget(key, IPC_CREAT|0600);
    if (msgid == -1) {
        err_sys("msgget failed");
    }

    if (msgctl(msgid, IPC_STAT, &msg_buf) == -1) {
        err_sys("msgctl failed");
    }

    printf("key: 0x%x, msgid: %d\n", key, msgid);
    printf("msg_perm.uid: %d\n", msg_buf.msg_perm.uid);
    printf("msg_perm.gid: %d\n", msg_buf.msg_perm.gid);
    printf("msg_stime: %d\n", msg_buf.msg_stime);
    printf("msg_rtime: %d\n", msg_buf.msg_rtime);
    printf("msg_qnum: %d\n", msg_buf.msg_qnum);
    printf("msg_qbytes: %d\n", msg_buf.msg_qbytes);
}

int
main(void) {
    mq_status();
}

The demo of send message .

#include "apue.h"

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <string.h>

#define PATH    "./mq_x"
#define ID      1234
#define MSG     "hello future"

struct mymesg {
    long mtype;
    char mtext[512];
};


void
mq_send(void) {
    int msgid;
    key_t key;
    struct mymesg mesg;

    key = ftok(PATH, ID);
    if (key == -1) {
        err_sys("ftok failed");
    }

    msgid = msgget(key, IPC_CREAT|0600);
    if (msgid == -1) {
        err_sys("msgget failed");
    }

    mesg.mtype = 1;
    strncpy(mesg.mtext, MSG, strlen(MSG));
    if (msgsnd(msgid, &mesg, strlen(mesg.mtext), 0) == -1) {
        err_sys("msgsnd failed");
    }

}



int
main(void) {
    mq_send();
}

The demo of recv message.

#include "apue.h"

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <string.h>

#define PATH    "/home/keqiang/workspace/c/apue/mq_x"
#define ID      1234
#define MSG     "hello future"

struct mymesg {
    long mtype;
    char mtext[512];
};



void 
mq_recv(void) {
    int msgid;
    key_t key;
    struct mymesg mesg;

    key = ftok(PATH, ID);
    if (key == -1) {
        err_sys("ftok failed");
    }

    msgid = msgget(key, IPC_CREAT|0600);
    if (msgid == -1) {
        err_sys("msgget failed");
    }

    if (msgrcv(msgid, &mesg, 512, 1, 0) == -1) {
        err_sys("msgrcv failed");
    }

    printf("mtype: %ld\n", mesg.mtype);
    printf("mtext: %s\n", mesg.mtext);

}

int
main(void) {
    mq_recv();
}

The type argument lets us specify which message we want.

  • type == 0 The first message on the queue is returned.
  • type > 0 The first message on the queue whose message type equals type is returned.
  • type < 0 The first message on the queue whose message type is the lowest value less than or equal to the absolute value of type is returned.

The last flag argument, we can specify a flag value of

  • IPC_NOWAIT, to make the operation nonblocking, causing msgrcv to return −1 with errno set to ENOMSG if a message of the specified type is not available. If IPC_NOWAIT is not specified, the operation blocks until a message of the specified type is available, the queue is removed from the system (−1 is returned with errno set to EIDRM), or a signal is caught and the signal handler returns (causing msgrcv to return −1 with errno set to EINTR).
  • MSG_COPY
  • MSG_NOERROR, If the returned message is larger than nbytes and the MSG_NOERROR bit in flag is set, the message is truncated.If the message is too big and this flag value is not specified, an error of E2BIG is returned instead (and the message stays on the queue)

results matching ""

    No results matching ""