• Linux消息队列


    POSIX消息队列

    • 使用man mq_overview命令查看POSIX消息队列编程手册
    • 头文件:include
    • 从消息队列中取出的是优先级最高且最先进入消息队列的消息

    接收消息

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define MQ_NAME     "/my_mq"            //必须以斜杠/开头
    
    struct msg_t {
        int32_t data;
    };
    
    int main()
    {
        int len = sizeof(struct msg_t);
    
        struct mq_attr attr = {
                .mq_maxmsg = 10,    //消息队列大小
                .mq_msgsize = len,   //每个消息的大小
        };
    
        mqd_t  mq_fd = mq_open(MQ_NAME,O_CREAT | O_RDONLY, 0666, &attr);
        if (mq_fd == -1)
        {
            printf("mq_open failed: %s\n", strerror(errno));
            return 0;
        }
        struct msg_t msg;
        unsigned int prio;
        long ret = mq_receive(mq_fd, (char*)&msg,len, &prio);
        if (ret == -1)
        {
            printf("mq_send: %s\n", strerror(errno));
        }
        printf("mq received %ld bytes\n", ret);
        printf("%d %d\n",msg.data, prio);
    
        mq_close(mq_fd);
        mq_unlink(MQ_NAME);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    监听消息

    • 消息通知触发的条件:消息队列为空,且有新消息到达时
    • 监听消息队列注册后只能触发1次,触发后需要重新注册
    • 同时只能有一个进程注册消息队列监听
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define MQ_NAME     "/my_mq"            //必须以斜杠/开头
    
    struct msg_t {
        int32_t data;
    };
    
    static void handle_mq_msg(union sigval sv)
    {
    
        mqd_t mq_fd = *((mqd_t*) sv.sival_ptr);
        struct msg_t msg;
        unsigned int prio;
    
    
    
        int ret = mq_receive(mq_fd, (char*)&msg,sizeof(struct msg_t), &prio);
        if (ret == -1)
        {
            printf("mq_receive failed: %s\n", strerror(errno));
        }
        printf("mq received %ld bytes\n", ret);
        printf("%d %d\n",msg.data, prio);
    
        ret = mq_notify(mq_fd, &sev);			//需要重新注册
        if (ret == -1)
        {
            printf("mq_notify failed: %s\n", strerror(errno));
        }
    }
    
    int main()
    {
        int len = sizeof(struct msg_t);
    
        struct mq_attr attr = {
                .mq_maxmsg = 10,    //消息队列大小
                .mq_msgsize = len,   //每个消息的大小
        };
    
        mqd_t  mq_fd = mq_open(MQ_NAME,O_CREAT | O_RDONLY, 0666, &attr);
        if (mq_fd == -1)
        {
            printf("mq_open failed: %s\n", strerror(errno));
            return 0;
        }
    
        struct sigevent sev = {
                .sigev_notify = SIGEV_THREAD,
                .sigev_notify_function = handle_mq_msg,
                .sigev_notify_attributes = NULL,
                .sigev_value.sival_ptr = &mq_fd,
        };
        int ret = mq_notify(mq_fd, &sev);
        if (ret == -1)
        {
            printf("mq_notify failed: %s\n", strerror(errno));
        }
    
        pause();
        mq_close(mq_fd);
        mq_unlink(MQ_NAME);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    发送消息

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define MQ_NAME     "/my_mq"            //必须与接收进程使用的消息队列同名
    
    struct msg_t {
        int32_t data;
    };
    
    int main()
    {
    
        mqd_t  mq_fd = mq_open(MQ_NAME,O_WRONLY);
        if (mq_fd == -1)
        {
            printf("mq_open failed: %s\n", strerror(errno));
            return 0;
        }
        struct msg_t msg = {8888};
    
        long ret = mq_send(mq_fd, (char*)&msg, sizeof(struct msg_t), 1);
        if (ret == -1)
        {
            printf("mq_send: %s\n", strerror(errno));
            return 0;
        }
        printf("mq send successfully\n");
    
        mq_close(mq_fd);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    System V消息队列

  • 相关阅读:
    vue3+ts+uniapp实现小程序端input获取焦点计算上推页面距离
    《HTML+CSS+JavaScript》之第22章 浮动布局
    JSP学生成长档案管理系统myeclipse开发sql数据库BS模式java编程网页结构
    Python 多线程之threading介绍
    推理还是背诵?通过反事实任务探索语言模型的能力和局限性
    文本搜索小程序
    拉电流、灌电流和漏电流
    一、K近邻算法K-NN(有监督学习)
    springboot单元测试
    正则化项和L1范数和L2范数的关系
  • 原文地址:https://blog.csdn.net/AcTarjan/article/details/134439500