消息队列(Message Queue)是一种进程间通信(IPC)机制,它允许进程通过在队列中添加和读取消息来交换数据。与管道(命名/匿名)相比,消息队列具有结构化消息异步通信消息持久化等特点,更适合复杂的进程间数据交换场景。

核心特性

  1. 消息结构化
    每个消息都有一个类型标识(通常是整数)和数据内容,接收进程可以根据类型选择性读取消息,而无需按顺序处理所有数据。

  2. 异步通信
    发送进程发送消息后无需等待接收进程立即处理,可继续执行其他操作;接收进程可在需要时读取消息,两者无需同步运行。

  3. 消息持久化
    消息存储在内核空间,即使发送进程退出,消息也会保留在队列中,直到被接收进程读取或手动删除。

  4. 多进程交互
    多个进程可以向同一消息队列发送消息,也可以从队列中读取消息(通过类型筛选实现一对一、一对多通信)。

消息队列的使用(System V 消息队列,Linux 为例)

System V 消息队列是最常用的实现,通过以下系统调用操作:

  • msgget():创建或获取消息队列
  • msgsnd():发送消息到队列
  • msgrcv():从队列接收消息
  • msgctl():控制消息队列(如删除、获取状态)
1. 消息结构定义

消息需要按固定格式定义,包含类型和数据:

#include <sys/msg.h>// 消息结构(必须以 long 类型的 mtype 开头)
struct msgbuf {long mtype;       // 消息类型(>0)char mtext[1024]; // 消息数据(可自定义大小和类型)
};
2. 创建/获取消息队列(msgget)
// 创建或获取消息队列,返回队列 ID
int msgid = msgget(key_t key, int flags);
  • key:用于标识消息队列的键值(可通过 ftok() 生成唯一键)
  • flags:创建权限和操作标志(如 IPC_CREAT | 0666 表示创建队列,权限为 666)
3. 发送消息(msgsnd)
// 向队列发送消息,成功返回 0,失败返回 -1
int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg);
  • msgid:消息队列 ID
  • msgp:指向消息结构的指针
  • msgsz:消息数据部分(mtext)的长度
  • msgflg:发送标志(0 表示阻塞,IPC_NOWAIT 表示非阻塞)
4. 接收消息(msgrcv)
// 从队列接收消息,成功返回接收的字节数,失败返回 -1
ssize_t msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
  • msgtyp:指定接收的消息类型(0 接收任意类型,>0 接收指定类型,<0 接收小于等于其绝对值的类型)
  • 其他参数同 msgsnd
5. 控制消息队列(msgctl)
// 控制消息队列(如删除),成功返回 0,失败返回 -1
int msgctl(int msgid, int cmd, struct msqid_ds *buf);
  • cmd:操作命令(IPC_RMID 表示删除队列)

完整示例

发送进程(sender.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/msg.h>
#include <sys/ipc.h>struct msgbuf {long mtype;char mtext[1024];
};int main() {// 生成唯一键(文件路径和项目ID需与接收进程一致)key_t key = ftok("/tmp", 'A');if (key == -1) {perror("ftok failed");exit(1);}// 创建或获取消息队列int msgid = msgget(key, IPC_CREAT | 0666);if (msgid == -1) {perror("msgget failed");exit(1);}// 准备消息(类型为 1,数据为 "Hello, receiver!")struct msgbuf msg;msg.mtype = 1;strcpy(msg.mtext, "Hello, receiver!");// 发送消息if (msgsnd(msgid, &msg, strlen(msg.mtext) + 1, 0) == -1) {perror("msgsnd failed");exit(1);}printf("发送消息: %s\n", msg.mtext);return 0;
}
接收进程(receiver.c)
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <sys/ipc.h>struct msgbuf {long mtype;char mtext[1024];
};int main() {// 生成与发送进程相同的键key_t key = ftok("/tmp", 'A');if (key == -1) {perror("ftok failed");exit(1);}// 获取消息队列(不创建,只连接已存在的)int msgid = msgget(key, 0666);if (msgid == -1) {perror("msgget failed");exit(1);}// 接收消息(只接收类型为 1 的消息)struct msgbuf msg;ssize_t n = msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0);if (n == -1) {perror("msgrcv failed");exit(1);}printf("接收消息: %s\n", msg.mtext);// 接收完成后删除消息队列(可选)if (msgctl(msgid, IPC_RMID, NULL) == -1) {perror("msgctl failed");exit(1);}return 0;
}

运行方式

  1. 先编译并运行接收进程(会阻塞等待消息)。
  2. 再编译并运行发送进程(发送消息后,接收进程会立即输出并删除队列)。

关键注意事项

  1. 消息类型的作用
    接收进程可通过 msgtyp 筛选消息,例如:

    • 按优先级处理(高类型消息优先)
    • 实现多进程定向通信(不同进程使用不同类型)
  2. 消息大小限制
    系统对单条消息的大小有限制(可通过 msgmax 配置),超过限制会导致发送失败。

  3. 队列容量限制
    消息队列的总字节数也有限制(msgmnb),满队列时发送操作会阻塞(非阻塞模式下返回错误)。

  4. 资源释放
    消息队列不会自动销毁,需通过 msgctl(..., IPC_RMID, ...) 手动删除,否则会残留内核中占用资源。

  5. 与其他 IPC 的对比

    机制特点适用场景
    消息队列结构化消息、异步、按类型读取复杂数据交换、多进程通信
    管道流式数据、简单、顺序读取简单命令交互、父子进程通信
    共享内存速度最快、直接访问内存高频数据交换、大数据量传输
    信号量用于同步和互斥,不传递数据控制进程对共享资源的访问

应用场景

  • 分布式系统中的进程协作(如服务端与多个客户端的消息交互)。
  • 日志收集系统(不同进程按类型发送日志,收集进程分类处理)。
  • 任务调度(调度进程发送任务消息,工作进程按类型接收并执行)。

消息队列通过结构化和异步特性,简化了复杂进程间通信的设计,是中大型系统中常用的 IPC 方案。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac中多版本JDK配置和切换

下载 从jdk官网下载即可&#xff0c;找到自己要用的版本。 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/#jdk21-mac 我这里下载的jdk1.8和21。 根据自己芯片下载&#xff0c;一般都是m芯片。下载好后&#xff0c;点击&#xff0c;一直下一步就行&…

【JVM】流程汇总

【JVM】流程汇总【一】编译过程和内存分布【1】案例程序&#xff1a;简单的 Java 类【2】Java 编译过程&#xff1a;从.java到.class&#xff08;1&#xff09;编译命令&#xff08;2&#xff09;编译结果&#xff08;3&#xff09;字节码的作用【3】Java 运行过程&#xff1a;…

专业MP3瘦身工具WinMP3Shrink 1.1,绿色单文件,极速压缩

[软件名称]: 专业MP3瘦身工具WinMP3Shrink 1.1 [软件大小]: 1.1 MB [软件大小]: 夸克网盘 | 百度网盘 软件介绍 WinMP3Shrink 是一款免费的 MP3 压缩软件&#xff0c;能够有效减少 MP3 文件的体积&#xff0c;同时还能增强音质。即使不重新编码&#xff0c;通过移除保留空间…

LeetCode 每日一题 2025/8/4-2025/8/10

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录8/4 904. 水果成篮8/5 3477. 水果成篮 II8/6 3479. 水果成篮 III8/7 3363. 最多可收集的水果数目8/8 808. 分汤8/9 231. 2 的幂8/10 869. 重新排序得到 2 的幂8/4 904. 水果…

Python爬虫实战:研究Ruia框架,构建博客园文章采集系统

1. 引言 1.1 研究背景与意义 在数字化时代,数据已成为驱动科技创新与产业升级的核心生产要素。互联网作为全球最大的信息载体,蕴含着亿级结构化、半结构化与非结构化数据,这些数据在商业决策、学术研究、公共服务等领域具有不可替代的价值。网络爬虫技术作为自动获取网络公…

Office安装使用?借助Ohook开源工具?【图文详解】微软Office产品

一、问题背景 很多用户在使用 Office 软件一段时间后&#xff0c;会遇到以下问题。 二、解决方案 Ohook 是 Office 独有的可用方式&#xff0c;源自 GitHub 上的开源项目&#xff0c;代码开源&#xff08;开源地址&#xff1a;https://github.com/asdcorp/ohook&#xff09;。 …

LeetCode简单题 - 学习

力扣题库 - 简单题 - 仅记录学习 来源地址&#xff1a; 力扣 (LeetCode) 全球极客挚爱的技术成长平台 1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你…

Android Camera 打开和拍照APK源码

完整下载路径: 【免费】AndroidcameraAPK完整源码(包括打开摄像头和拍照保存功能)Android10验证可完整运行资源-CSDN下载 效果: 源码: package com.example.mycamera;import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appco…

【系统分析师】软件需求工程——第11章学习笔记(上)

软件需求工程是包括创建和维护软件需求文档所必需的一切活动的过程。可分为两大工作&#xff1a;需求开发需求获取需求分析需求定义&#xff08;编写需求规格说明书&#xff09;需求验证需求管理定义需求基线处理需求变更需求跟踪在需求开发阶段需要确定软件所期望的用户类型&a…

机器学习第七课之支持向量机SVM

目录 简介&#xff1a; 一、什么是支持向量机 二、如何选取最佳的超平面 1.超平面方程 (优化目标) 2.如何寻找最优的超平面 3.举例分析 4.软间隔​编辑 三、核函数 1举例 2常用核函数 3.多项式核函数 4.高斯核函数: 四、svm的优缺点 五、支持向量机的API 六、案例…

P3232 [HNOI2013] 游走,solution

原题&#xff1a; link&#xff0c;点击这里喵。 题意&#xff1a; 给定一个 nnn 个点 mmm 条边的无向连通图&#xff0c;图无重边和自环&#xff0c;顶点从 111 编号到 nnn&#xff0c;边从 111 编号到 mmm。 小 Z 在该图上进行随机游走&#xff0c;初始时小 Z 在 111 号顶…

Docker容器部署discuz论坛与线上商城

准备 关闭防火墙&#xff0c;上下文[rootdocker ~]# systemctl disable --now firewalld[rootdocker ~]# setenforce 0下载应用yum remove runc -y ### rocky8才需要yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/cento…

Linux入门指南:26个基础命令全解析

目录 一.基础概念与入门 1.Linux操作系统简介 2.终端与shell的基本概念 3.命令行界面的优势 二.基础指令 1.whoami ​2.useradd/userdel/passwd ​3.pwd ​4.ls ​5.cd 6.touch 7.mkdir 8.tree 9.rmdir/rm 10.man 11.cp 12.mv 13.cat 14.le…

【后端】Java 8 特性 `User::getId` 语法(方法引用)介绍

文章目录核心概念解析&#xff1a;方法引用的四种类型&#xff1a;关键特性&#xff1a;使用场景推荐&#xff1a;何时避免使用&#xff1a;性能说明&#xff1a;在 Java 中&#xff0c; User::getId 是一种称为 方法引用&#xff08;Method Reference&#xff09; 的语法糖&a…

基于BP与CNN的图像分类模型构建、超参数优化及性能对比研究​

一、实验目的实验目标构建基于神经网络模型的数据分析与模式识别框架&#xff0c;探明神经网络在大数据分析中的意义。实验任务构建基于深度 BP 神经网络与卷积神经网络的数据分析与模式识别框架&#xff0c;将数据集 MNIST 与 CIFAR-10 分别在两种模型中训练&#xff0c;并比较…

HarmonyOS应用开发-低代码开发登录页面(超详细)

本篇文章我来手把手教大家做一个HarmonyOS 应用的登录页面&#xff0c;逐步讲解&#xff0c;非常细致&#xff0c;百分百能学会&#xff0c;并提供全部源码。页面使用 DevEco Studio 的低代码开发。 通过本文的实践经验&#xff0c;我想告诉大家&#xff0c; HarmonyOS 应用开发…

AJAX与axios框架

文章目录前言案例跨域访问总结❗前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 通过 ajax 进行前后端交互 案例 此项目用到了javaweb知识 首先创建JavaWeb项目编写代码&#xff1a; package ajax;import java.io.IOException; import java.util.Arr…

智能创造的幕后推手:AIGC浪潮下看AI训练师如何塑造智能未来

文章目录一、AIGC时代的算法与模型训练概览二、算法与模型训练的关键环节三、AI训练师的角色与职责四、AI训练师的专业技能与素养五、AIGC算法与模型训练的未来展望《AI训练师手册&#xff1a;算法与模型训练从入门到精通》亮点内容简介作者简介谷建阳目录《医学统计学从入门到…

Python设计模式 - 装饰模式

定义 装饰模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;用于在不修改原有类的情况下动态地扩展对象的功能。 结构抽象组件&#xff08;Component&#xff09;&#xff1a;定义对象的公共接口&#xff0c;使得客户端能以一致的方式处理未被装…

MySQL(188)如何使用MySQL的慢查询工具?

使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询。以下是详细深入的步骤和代码示例&#xff0c;帮助你使用MySQL的慢查询工具来进行查询分析和优化。 一、启用慢查询日志 首先&#xff0c;你需要确保MySQL的慢查询日志功能是启用的。慢查询日志记录了所有执行…