System V 消息队列概述

System V消息队列使用消息队列标识符标识,对于内核中的每个消息队列,内核维护一个定义在<sys/msg.h>头文件中的信息结构。

struct msqid_ds
  {
    struct msqid_ds {
    struct ipc_perm msg_perm;
    struct msg *msg_first;      /* first message on queue,unused  */
    struct msg *msg_last;       /* last message in queue,unused */
    __kernel_time_t msg_stime;  /* last msgsnd time */
    __kernel_time_t msg_rtime;  /* last msgrcv time */
    __kernel_time_t msg_ctime;  /* last change time */
    unsigned long  msg_lcbytes; /* Reuse junk fields for 32 bit */
    unsigned long  msg_lqbytes; /* ditto */
    unsigned short msg_cbytes;  /* current number of bytes on queue */
    unsigned short msg_qnum;    /* number of messages in queue */
    unsigned short msg_qbytes;  /* max number of bytes on queue */
    __kernel_ipc_pid_t msg_lspid;   /* pid of last msgsnd */
    __kernel_ipc_pid_t msg_lrpid;   /* last receive pid */

};

msgget函数:

创建一个新的消息队列或者访问一个已存在的消息队列。

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgget(key_t key, int msgflg);

key是通过ftok的返回值,也可以是常值IPC_PRIVATE。oflag值是读写权限值的组合,它还可以与IPC_CREAT和IPC_EXCL按位或。

msgsnd和msgrcv函数:
打开一个消息队列后,使用此函数往其上放置一个消息和读取一个消息
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       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);
msgflg可以是0也可以是IPC_NOWAIT。
对于type的选项:
为0的话,返回队列中的第一个消息
为大于0的话,返回类型值为type的第一个消息。
小于0的话,返回类型值小于type参数绝对值的消息中类型值最小的。

msgctl函数:
提供在一个消息队列上的各种控制操作
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

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

例子:

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

int main(int argc, char **argv)
{
    int c, oflag, mqid;
    oflag = IPC_CREAT | 00666;

    while ((c = getopt(argc, argv, "e")) != -1) {
        switch(c) {
            case 'e':
                oflag |= IPC_EXCL;
                 break;
        } 
    }
    printf("the optind is %d, the argc is %d\n", optind, argc);
    if (optind != argc - 1) {
        printf("usage: msgcreate [-e] <pathname>");
        exit(0);
    }
    printf("argv[optind] is %s \n",argv[optind]);
    if ((mqid = msgget(ftok(argv[optind], 0), oflag)) < 0); {
        perror("msgget error\n");
        exit(0);
    }
    exit(0);
}



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <errno.h>

struct msgbuf {
    long mtype;
    char mtext[1];
}; 

int main(int argc, char **argv)
{
     int mqid;
    size_t len;
    long type;
    struct msgbuf *ptr;
    int n;

    if (argc != 4) {
        printf("usage: msgsnd <pathmane> <#bytes> <type>");
        exit(0);
    }

    len = atoi(argv[2]);
    type = atoi(argv[3]);
    if ((mqid = msgget(ftok(argv[1],0), 00200)) == -1) {
        perror("msgget error");
        exit(0);
    }

    ptr = calloc(sizeof(long) + len, sizeof(char));
    ptr->mtype = type;

    n = msgsnd(mqid, ptr, len, 0);
    if (n < 0) 
        perror("msgsend erro");
    printf("the size of send is %d\n", n);

    exit(0);
}




#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <fcntl.h>

#define MAXMSG (8192 + sizeof(long))

struct msgbuf {
    long mtype;
    char mtext[1];
};

int main(int argc, char **argv) 
{
    int c, flag, mqid;
    long type;
    ssize_t n;
    struct msgbuf *buff;

    type = flag = 0;

    while ((getopt(argc, argv, "nt:")) != -1) {
        switch(c) {
            case 'n':
                flag |= IPC_NOWAIT;
                break;
            case 't':
                type = atol(optarg);
                break;
        }
    }

    if (optind != argc - 1) {
        printf("usage: msgrcv [-n] [-t type] <pathname>");
        exit(0);
    }

    if ((mqid = msgget(ftok(argv[optind], 0), O_RDONLY)) == -1) {
        printf("msgget error");
        exit(0);
    }

    buff = malloc(MAXMSG);

    n = msgrcv(mqid, buff, MAXMSG, type, flag);
    printf("read %d bytes, type = %ld\n", n, buff->mtype);

    exit(0);
}








你可能感兴趣的:(System V 消息队列概述)