posix消息隊列概述以及限制

消息隊列能夠當作一個消息鏈表,不一樣於FIFO和管道,某個進程往一個消息隊列寫入消息以前,不須要另外進程在該隊列上等待消息的到達。函數

對posix消息隊列的讀老是返回最高優先級的最先消息。code

經常使用函數:隊列

建立或者打開一個消息隊列:進程

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

關閉消息隊列:get

       #include <mqueue.h>

       int mq_close(mqd_t mqdes);
刪除消息隊列:消息隊列

posix消息隊列具有隨內核的持續性,就是說即便當前沒有進程打開某個消息隊列,該隊列上的消息也將一直存在。it

       #include <mqueue.h>

       int mq_unlink(const char *name);

要真正的刪除一個消息隊列得這樣:調用mq_unlink並讓它的引用計數(close一次減小1)達到0。io

獲取消息隊列屬性:class

       #include <mqueue.h>

 

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

 

       int mq_setattr(mqd_t mqdes, struct mq_attr *newattr,

                        struct mq_attr *oldattr);

其中消息隊列屬性結構體以下:
           struct mq_attr {
               long mq_flags;       /* Flags: 0 or O_NONBLOCK */
               long mq_maxmsg;      /* Max. # of messages on queue */
               long mq_msgsize;     /* Max. message size (bytes) */
               long mq_curmsgs;     /* # of messages currently in queue */
           };

接收和發送消息:
       #include <mqueue.h>

       int mq_send(mqd_t mqdes, const char *msg_ptr,
                     size_t msg_len, unsigned msg_prio);
       #include <mqueue.h>

       ssize_t mq_receive(mqd_t mqdes, char *msg_ptr,
                          size_t msg_len, unsigned *msg_prio);


消息隊列限制:
總共有四個限制,分別爲:
mq_mqxmsg;mq_msgsize;
MQ_OPEN_MAX;MQ_PRIO_MAX:這兩個是在<unistd.h>頭文件裏定義的,能夠用sysconf獲取。


例子:建立消息隊列
代碼:
//mqcreate.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#define FILEMODE (S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP)
struct mq_attr attr;//消息隊列屬性結構體

int main(int argc, char **argv)
{
    int c, flags;
    mqd_t mqd;

    flags = O_RDWR | O_CREAT;
    while((c = getopt(argc, argv, "em:z:")) != -1) {//處理參數,帶冒號的表示後面有參數的
        switch(c) {
            case 'e':
                flags |= O_EXCL;
                printf("the optind is :%d\n",optind);
                break;
            case 'm':
                attr.mq_maxmsg = atol(optarg);
                printf("the optind is :%d\n",optind);
                break;
            case 'z':
                attr.mq_msgsize = atol(optarg);
                printf("the optind is :%d\n",optind);
                break;
        }
    }
    if (optind != argc - 1) {
        printf("usage: mqcreate [-e] [-m maxmsg -z msgsize] <name>");
        exit(0);
    }
    
    if ((attr.mq_maxmsg != 0 && attr.mq_msgsize == 0) || (attr.mq_maxmsg == 0 && attr.mq_msgsize !=0)){
        printf("must specify both -m maxmsg and -z msgsize");
        exit(0);
    }

    mqd = mq_open(argv[optind], flags, FILEMODE, (attr.mq_maxmsg != 0) ? &attr : NULL);
    mq_close(mqd);
    exit(0);
}

例子:發送消息
代碼:
//mqsend.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>


int main(int argc, char **argv)
{
    mqd_t mqd;
    void *ptr;
    size_t len;
    unsigned int prio;

    if (argc != 4) {
        printf("usage: mqsend <name> <#bytes> <priority>");
        exit(0);
    }
    len = atoi(argv[2]);
    prio = atoi(argv[3]);
    
    if ((mqd = mq_open(argv[1], O_WRONLY)) == -1){
        printf("open error");
        exit(0);
    }
    ptr = calloc(len, sizeof(char));
    mq_send(mqd, ptr, len, prio);
    exit(0);
}

例子:讀取一個消息
代碼:
//mqrecieve.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>

int main(int argc, char **argv)
{
    int c, flags;
    mqd_t mqd;
    ssize_t n;
    unsigned int prio;
    void *buff;
    struct mq_attr attr;
    flags = O_RDONLY;
    while((c = getopt(argc, argv, "n")) != -1){
        switch(c) {
            case 'n':
                flags |= O_NONBLOCK;
                break;
        }
    }
    if (optind != argc-1) {
        printf("usage: mqreceive [-n] <name>");
        exit(0);
    }

    mqd = mq_open(argv[optind], flags);
    mq_getattr(mqd, &attr);

    buff = malloc(attr.mq_msgsize);

    n = mq_receive(mqd, buff, attr.mq_msgsize, &prio);
    printf("read %ld bytes, priority = %u\n",(long) n,prio);
    exit(0);
}
相關文章
相關標籤/搜索