linux应用 进程间通信之消息队列(POSIX)

news2024/11/28 6:54:32

1、前言

1.1 定义

POSIX消息队列是Linux中一种进程间通信机制,允许进程通过发送和接收消息来交换数据。这些消息在队列中按优先级顺序存储和传递。

1.2 应用场景

  • 当多个进程需要共享或交换数据时。
  • 实现进程间的解耦和异步通信。
  • 作为缓冲区,处理速度不同的进程之间的数据传输。

1.3 优缺点

1.3.1 优点
  • 灵活,支持多种数据类型和优先级。
  • 可靠,消息持久化且不会因发送者崩溃而丢失。
  • 高效,支持大量数据的传输和并行处理。
1.3.2 缺点
  • 相比管道和信号,API更复杂。
  • 可能存在数据复制的开销。
  • 需要管理访问权限以确保安全性。

2、常用接口

2.1 mq_open()

打开一个已存在的消息队列,或创建一个新的消息队列。

mqd_t mq_open(const char *name, int oflag, ...);

入参:

  • name:消息队列的名称。
  • oflag:打开或创建队列时的选项标志,可以是以下一个或多个选项的按位或:
    • O_RDONLY:以只读方式打开消息队列。
    • O_WRONLY:以只写方式打开消息队列。
    • O_CREAT:如果指定的消息队列不存在,则创建它。
    • O_EXCL:与O_CREAT一起使用,如果消息队列已存在,则返回错误。
  • 如果使用了O_CREAT标志,还需要提供两个额外的参数:mode_t modestruct mq_attr *attrmode指定新队列的权限,attr指定队列的属性;否则,这两个参数可以省略。

返回值:

  • 成功时返回一个消息队列描述符(mqd_t类型),失败时返回-1并设置errno

2.2 mq_send() 和 mq_timedsend()

向指定的消息队列发送消息。

int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio);
int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);

入参:

  • name:消息队列的名称。
  • oflag:打开或创建队列时的选项标志,可以是以下一个或多个选项的按位或:
    • O_RDONLY:以只读方式打开消息队列。
    • O_WRONLY:以只写方式打开消息队列。
    • O_CREAT:如果指定的消息队列不存在,则创建它。
    • O_EXCL:与O_CREAT一起使用,如果消息队列已存在,则返回错误。
  • 如果使用了O_CREAT标志,还需要提供两个额外的参数:mode_t modestruct mq_attr *attrmode指定新队列的权限,attr指定队列的属性;否则,这两个参数可以省略。

返回值:

  • 成功时返回一个消息队列描述符(mqd_t类型),失败时返回-1并设置errno

2.3 mq_receive() 和 mq_timedreceive()

从指定的消息队列接收消息。

ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout);

入参:

  • mqdes:消息队列描述符。
  • msg_ptr:指向接收消息的缓冲区的指针。
  • msg_len:接收消息的最大长度。
  • msg_prio:指向存储接收消息优先级的变量的指针。
  • abs_timeout(仅mq_timedreceive()):指向timespec结构的指针,指定了接收操作的绝对超时时间;如果为NULL,则不设置超时。

返回值:

  • 成功时返回接收到的消息长度,失败时返回-1并设置errno

2.4 mq_close()

关闭一个打开的消息队列描述符。

int mq_close(mqd_t mqdes);

入参:

  • mqdes:消息队列描述符。

返回值:

  • 成功时返回0,失败时返回-1并设置errno

2.5 mq_unlink()

删除一个命名的消息队列。

int mq_unlink(const char *name);

入参:

  • name:要删除的消息队列的名称。

返回值:
成功时返回0,失败时返回-1并设置errno

2.6 mq_getattr() 和 mq_setattr()

mq_getattr()获取消息队列的属性;mq_setattr()设置消息队列的属性,并可以选择性地获取旧的属性。

int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat);

入参:

  • mqdes:消息队列描述符。
  • mqstat:指向mq_attr结构的指针,用于存储或设置消息队列的属性。
  • omqstat(仅mq_setattr()):如果非NULL,则在此结构中返回旧的队列属性。

返回值:
成功时返回0,失败时返回-1并设置errno

3、编程测试

测试代码如下,编译需要加-lrt:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <fcntl.h>  
#include <sys/stat.h>  
#include <mqueue.h>  
#include <errno.h>  
#include <unistd.h>  
#include <time.h>

#define QUEUE_NAME  "/mesg_p"  
#define MAX_SIZE    1024  

// 打印时分秒的宏        
#define PRINT_MIN_SEC do { \
            time_t t = time(NULL); \
            struct tm *tm_ptr = localtime(&t); \
            printf("%02d:%02d:%02d:", tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec);\
        } while (0);printf

int main(int argc, char *argv[]) 
{  
    mqd_t mqdes;  
    char buf[MAX_SIZE] = {0};  
    struct mq_attr attr;  

    // 命令行参数 
    // 第一个参数      S表示发送 R表示接收 D表示删除
    if (argc != 2) 
    {
        printf("Usage: %s S|R|D", argv[0]);
        return 0;
    }
    
    // 设置消息队列属性  
    attr.mq_flags = 0;  
    attr.mq_maxmsg = 10;  
    attr.mq_msgsize = MAX_SIZE;  
    attr.mq_curmsgs = 0;  
  
    // 打开或创建消息队列  
    mqdes = mq_open(QUEUE_NAME, O_CREAT | O_RDWR, 0644, &attr);  
    if (mqdes == (mqd_t) -1) 
    {  
        perror("mq_open");  
        exit(1);  
    }  

    if (!strcmp(argv[1], "S"))
    {
        // 发送消息  
        strcpy(buf, "Mesg 12345678!");  
        if (mq_send(mqdes, buf, strlen(buf) + 1, 0) == -1) 
        {  
            perror("mq_send");  
            exit(1);  
        } 
        PRINT_MIN_SEC("Send: %s\n", buf); 
    } 
    else if (!strcmp(argv[1], "R")) 
    {
        // 接收消息  
        memset(buf, 0, sizeof(buf));  
        if (mq_receive(mqdes, buf, MAX_SIZE, NULL) == -1) 
        {  
            perror("mq_receive");  
            exit(1);  
        }  
        
        PRINT_MIN_SEC("Received: %s\n", buf); 
    } 
    else if (!strcmp(argv[1], "D")) 
    {
        // 删除消息队列  
        if (mq_unlink(QUEUE_NAME) == -1) 
        {  
            perror("mq_unlink");  
            exit(1);  
        } 
    } 
    else
    {
        printf("Usage: %s S|R|D", argv[0]);
        return 0;
    }
 
    // 关闭消息队列  
    if (mq_close(mqdes) == -1) 
    {  
        perror("mq_close");  
        exit(1);  
    }  
  
    return 0;  
}

使用不同的传参完成指定操作,S表示发送 R表示接收 D表示删除,启用两个进程测试数据收发:

测试删除:

4、总结

本文阐述了进程间通信之消息队列(POSIX)的定义、应用场景、优缺点等,列举了编程中使用的接口,编写了测试用例测试相关功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1448413.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指offer——二进制中1的个数

目录 1. 题目描述2. 可能引起死循环的想法3. 改进后的代码4. 给面试官惊喜的代码 1. 题目描述 请实现一个函数&#xff0c;输入一个整数&#xff0c;输出该数二进制表示中1的个数。例如把9表示成二进制位1001&#xff0c;有2位是1&#xff0c;因此如果输入9&#xff0c;该函数输…

Javaweb之SpringBootWeb案例之AOP概述及入门的详细解析

2.1 AOP概述 什么是AOP&#xff1f; AOP英文全称&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实说白了&#xff0c;面向切面编程就是面向特定方法编程。 那什么又是面向方法编程呢&#xff0c;为什么又需要面向…

概率论中不确定性的来源-简单不确定的规则

更多AI技术入门知识与工具使用请看下面链接&#xff1a; https://student-api.iyincaishijiao.com/t/iNSVmUE8/

openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存

文章目录 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存217.1 查看内存状况217.2 性能参数分析 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&…

酒店押金预授权怎么开通?微信酒店押金+房态+门锁关联 +电子押金单 解决方案

一、酒店押金管理有哪些&#xff1f; 1.渠道有银行预授权 2.微信押金支付 3.酒店押金系统 4.支付押金管理 二、银行预授权模式 酒店押金预授权通常是在客人办理入住时进行的&#xff0c;酒店会要求客人提供信用卡或借记卡的卡号、有效期、持卡人姓名等信息&#xff0c;然后…

Vue源码系列讲解——模板编译篇【三】(HTML解析器)

目录 1. 前言 2. HTML解析器内部运行流程 3. 如何解析不同的内容 3.1 解析HTML注释 3.2 解析条件注释 3.3 解析DOCTYPE 3.4 解析开始标签 3.5 解析结束标签 3.6 解析文本 4. 如何保证AST节点层级关系 5. 回归源码 5.1 HTML解析器源码 5.2 parseEndTag函数源码 6. …

js toFixed函数精度问题

在使用toFixed函数会出现精度缺失问题&#xff0c;如下图 在2.55与1.45保留1位小数时&#xff0c;正常情况下应该为2.6与1.5&#xff0c;而toFixed函数得出的是2.5与1.4。这和计算机中小数存储有关。 小数运算不精确其实与下面三方面有关&#xff1a; 1、存储 2、运算 3、显示…

新项目,从0到1,SpringBoot+Vue.js权限管理系统,拿去做毕设

大家好&#xff0c;我是 jonssonyan 最近把以前做的权限管理系统重新整理了一下&#xff08;将一些不规范的地方规范了一下&#xff0c;并且在关键地方写了注释&#xff09;&#xff0c;代码全部开源&#xff0c;这个项目是以现在主流的前后端分离模式开发的&#xff0c;包含前…

课时27:内容格式化_输入格式化_EOF原理

3.2.1 EOF原理 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 场景需求 在运维岗位中&#xff0c;有非常多的场景需要我们在脚本中编写应用软件的配置文件。在这些应用软件的配置文件中&#xff0c;经常携带大量的格式&#xff0…

猫头虎分享已解决Bug || SyntaxError: Unexpected token o in JSON at position 1 ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Docker 镜像是什么?常用的镜像命令有哪些?

docker 镜像仓库相关的命令&#xff1a;Docker 镜像仓库是什么&#xff1f;有哪些镜像仓库命令&#xff1f;-CSDN博客 1. Docker 镜像 Docker 镜像是一个轻量级、独立、可执行的软件包&#xff0c;它包含了运行特定应用程序所需的所有内容&#xff1a;代码、运行时环境、系统工…

[计算机网络]---网络编程套接字

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、基础知识…

Web基础01-HTML+CSS

目录 一、HTML 1.概述 2.html结构解析 3.HTML标签分类 4.HTML标签关系 5.HTML空元素 6.HTML属性 7.常用标签 &#xff08;1&#xff09;HTML标签 &#xff08;2&#xff09;标题标签 &#xff08;3&#xff09;换/折行标签 &#xff08;4&#xff09;段落标签 &am…

Qt之条件变量QWaitCondition详解

QWaitCondition内部实现结构图&#xff1a; 相关系列文章 C之Pimpl惯用法 目录 1.简介 2.示例 2.1.全局配置 2.2.生产者Producer 2.3.消费者Consumer 2.4.测试例子 3.原理分析 3.1.辅助函数CreateEvent 3.2.辅助函数WaitForSingleObject 3.3.QWaitConditionEvent …

java客运管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java客运管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&#…

国产制造,欧美品质:爱可声助听器产品质量获国际认可

随着科技的发展和全球化的推进&#xff0c;越来越多的中国制造产品开始走向世界舞台。其中&#xff0c;爱可声助听器凭借其卓越的产品质量&#xff0c;成为了国产制造的骄傲。 国产制造指的是在中国境内生产的产品&#xff0c;欧美品质则是指产品在设计、生产、质量控制等方面…

不止于浏览器:掌握Node.js,开启全栈开发新篇章!

介绍&#xff1a;Node.js是一个基于Chrome V8引擎的JavaScript运行时环境&#xff0c;特别适合构建高性能的网络服务器和实时应用。具体介绍如下&#xff1a; 服务器端JavaScript&#xff1a;Node.js的核心优势之一是在服务器端运行JavaScript&#xff0c;这使得前端开发者可以…

KAJIMA CORPORATION CONTEST 2024(AtCoder Beginner Contest 340)ABCDEF 视频讲解

这场比较郁闷&#xff0c;C题短路&#xff0c;连续4次WA&#xff0c;导致罚时太多 A - Arithmetic Progression Problem Statement Print an arithmetic sequence with first term A A A, last term B B B, and common difference D D D. You are only given inputs for w…

【论文模型讲解】CLIP(Learning Transferable Visual Models From Natural Language Supervision)

文章目录 前言0 摘要1 Introduction and Motivating Work2 Approach2.0 模型整体结构2.1 数据集2.2 选择一种高效的预训练方法2.3 模型选择与缩放2.4 训练 3 实验3.1 zero-shot 迁移3.1.1 与 Visual N-grams 对比3.1.2 Prompt Engineering and Ensembling3.1.3 zero-shot CLIP …

【数据结构】哈希桶封装出map和set

利用之前的哈希桶封装出unordered_map和unordered_set。 这个封装并不简单&#xff0c;迭代器的使用&#xff0c;模板参数的繁多&#xff0c;需要我们一层一层封装。 map是一个k - v类型&#xff0c;set是k类型&#xff0c;那么就明确了如果需要封装&#xff0c;底层的tables…