zoukankan      html  css  js  c++  java
  • UNIX IPC: POSIX 消息队列

    首先在我的MAC OSX上试了一下虽然有_POSIX_MESSAGE_PASSING的宏定义,但是用gcc编译会提示没有mqueue.h头文件,先放一边。在Ubuntu上使用正常,不过POSIX消息队列通过ipcs命令是看不到的,需要通过如下方式进行查看:

    mount -t mqueue none /mnt
    ls -al /mnt

    ls列出的文件即为程序中创建的POSIX消息队列,消息队列的名称需要以“/”开头否则会提示参数非法。通过cat查看这个文件可以知道这个队列的一些参数如:

    hgf@ubuntu:~/ipc$ cat /mnt/testmq
    
    QSIZE:0 NOTIFY:0 SIGNO:0 NOTIFY_PID:0

    编译代码时需要加上-lrt参数,即连接Posix.1 realtime库,

    基本操作API

    mqd_t mq_open(const char* name, int oflag, ... /* mode_t mode, struct mq_attr attr */);
    
    int mq_close(mqd_t mqdes);
    
    int mq_unlink(const char* name);
    
    int mq_getattr(mqd_t mqdes, struct mq_attr* attr);
    
    int mq_setattr(mqd_t mqdes, struct mq_attr* attr, struct mq_attr* oattr);
    
    int mq_send(mqd_t mqdes, const char* buf, size_t len, unsigned int prior);
    
    int mq_receive(mqd_t mqdes, const char* buf, size_t len, unsigned int* priop);

    mqcreate.c (gcc mqcreate.c -lrt -o mqcreate)

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    #include <unistd.h>
    #include <getopt.h>
    
    struct mq_attr attr;
    
    int main(int argc, char** argv) {
        char opt;
        
        char* MQ_NAME = "/testmq";
        
        int OPEN_MODE = O_RDWR | O_CREAT;
        int FILE_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
        
    
        while((opt = getopt(argc, argv, "en:m:z:")) != -1) {
            switch(opt) {
                case 'e':
                    OPEN_MODE |= O_EXCL;
                    break;
                case 'm':
                    attr.mq_maxmsg = atol(optarg);
                    break;
                case 'z':
                    attr.mq_msgsize = atol(optarg);
                    break;
                case 'n':
                    MQ_NAME = optarg;
                    break;
            }
        }
    
        printf("msg queue name:%s
    msg max size: %ld
    msg per size: %ld
    ",
            MQ_NAME, attr.mq_maxmsg, attr.mq_msgsize);
        
        struct mq_attr* attrarg = NULL;
        if (attr.mq_maxmsg != 0) {
            attrarg = &attr;
        }
    
        mqd_t mq = mq_open(MQ_NAME, OPEN_MODE, FILE_MODE, attrarg);
        
        if (mq < 0) {
            perror("message queue create failed:");
            return 0;
        }
        
        return 0;
    }

    mqunlink.c (gcc mqunlink.c -lrt -o mqunlink)

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    
    int main(int argc, char** argv) {
        char* MQ_NAME = "/testmq";
    
        if (argc > 1) {
            MQ_NAME = argv[1];
        }
    
        int res = mq_unlink(MQ_NAME);
    
        if (res < 0) {
            perror("close message queue:");
        }
    
        return 0;
    }

    mqgetattr.c

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    
    int main(int argc, char** argv) {
        char* name = "/testmq";
        
        if (argc > 1) {
            name = argv[1];
        }
        
        mqd_t mq = mq_open(name, O_RDONLY);
        
        if (mq < 0) {
            perror("open message queue failed:");
            return 0;
        }
    
        struct mq_attr attr;
    
        mq_getattr(mq, &attr);
    
        printf("max #msgs = %ld, max #bytes/msg = %ld, #current = %ld
    ",
            attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs
        );
    
        int res = mq_close(mq);
    
        if (res != 0) {
            perror("close message queue failed:");
        }
        return 0;
    }

    mqsend.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.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("%s msg_queue_name message priority
    ", argv[0]);
            return -1;
        }
        
        mqd = mq_open(argv[1], O_WRONLY);
        
        if (mqd < 0) {
            perror("open message queue failed");
            return -1;
        }
    
        len = strlen(argv[2]) + 1;
    
        ptr = malloc(len);
        
        prio= atoi(argv[3]);
    
        strcpy(ptr, argv[2]);
    
        int res = mq_send(mqd, ptr, len, prio);
        
        if (res != 0) {
            perror("send msg faild");
            return -1;
        }
    
        return 0;
    }

    mqreceive.c

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    #include <getopt.h>
    
    int main(int argc, char** argv) {
        
        char opt;
    
        char* queue = "/testmq";
    
        int FILE_MODE = O_RDONLY;
    
        while ((opt = getopt(argc, argv, "xn:")) != -1) {
            switch (opt) {
                case 'n':
                    queue = optarg;
                    break;
                case 'b':
                    FILE_MODE |= O_NONBLOCK;
                    break;
            }
        }
    
        mqd_t mqd = mq_open(queue, FILE_MODE);
    
        if (mqd < 0) {
            perror("open message queue failed");
            return -1;
        }
        
    
        struct mq_attr attr;
        char* buffer = NULL;
        int prio;
    
        mq_getattr(mqd, &attr);
        buffer = malloc(attr.mq_msgsize + 1);
        
        for(;;) {
            int res = mq_receive(mqd, buffer, attr.mq_msgsize, &prio);
            if (res < 0) {
                perror("read msg fail");
                return;
            }
    
            printf("read msg size:%u, msg(%s), prio:%d
    ", res, buffer, prio);
            if (FILE_MODE & O_NONBLOCK) {
                sleep(1);
                printf(".");
            }
        }
        return 0;
    }
  • 相关阅读:
    some requirement checks failed
    FTP下载文件时拒绝登陆申请怎么办?
    Linux查看与设定别名
    如何编写shell脚本
    Linux shell是什么
    Linux命令大全之查看登陆用户信息
    Linux命令大全之挂载命令
    论第二次作业之输入输出格式怎么合格(才疏学浅说的不对轻点喷我)
    文件词数统计
    软件工程作业--第一周
  • 原文地址:https://www.cnblogs.com/lailailai/p/4317031.html
Copyright © 2011-2022 走看看