当前位置: 首页 > news >正文

消息队列(Message Queue)简介

消息队列是一种进程间通信(IPC)机制,允许不同进程通过发送和接收消息进行 异步通信。它的核心特点包括:

  • 解耦:消息队列解耦了生产者和消费者,简化了系统设计。

  • 持久化存储:支持将消息存储在队列中,保证数据不会丢失。

  • 流量控制:适用于分布式系统或需要流量控制的场景。

在 Linux 系统中,常用的消息队列实现包括 System V 消息队列POSIX 消息队列。这里将以 System V 消息队列 为例,介绍其 C 语言 API 的使用方法。


核心 API 函数 💻

1. 创建/获取消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);
  • key:队列的唯一标识符,通常通过 ftok 生成。

  • msgflg:权限标志(如 IPC_CREAT | 0666)。

  • 返回值:消息队列的 ID,失败返回 -1

2. 发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
  • msqid:消息队列 ID。

  • msgp:指向消息结构体的指针。

  • msgsz:消息数据部分的长度。

  • msgflg:标志(如 0IPC_NOWAIT)。

3. 接收消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
  • msgtyp:消息类型(0 表示任意类型)。

  • 其他参数与 msgsnd 类似。

4. 控制消息队列
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • cmd:控制命令(如 IPC_RMID 删除队列)。


消息结构体 📜

消息结构体包含一个 long 类型的消息类型字段,后跟消息数据部分:

struct msgbuf {
    long mtype;    // 消息类型(必须 > 0)
    char mtext[64]; // 消息数据(可自定义长度)
};

示例代码 📑

发送端(sender.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf {
    long mtype;
    char mtext[64];
};

int main() {
    key_t key = ftok(".", 'a'); // 生成唯一 key
    int msqid = msgget(key, IPC_CREAT | 0666);
    if (msqid == -1) {
        perror("msgget");
        exit(1);
    }

    struct msgbuf msg;
    msg.mtype = 1; // 消息类型
    strcpy(msg.mtext, "Hello from sender!");

    if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {
        perror("msgsnd");
        exit(1);
    }

    printf("Message sent: %s\n", msg.mtext);
    return 0;
}
接收端(receiver.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>

struct msgbuf {
    long mtype;
    char mtext[64];
};

int main() {
    key_t key = ftok(".", 'a');
    int msqid = msgget(key, 0666);
    if (msqid == -1) {
        perror("msgget");
        exit(1);
    }

    struct msgbuf msg;
    if (msgrcv(msqid, &msg, sizeof(msg.mtext), 1, 0) == -1) { // 接收类型为 1 的消息
        perror("msgrcv");
        exit(1);
    }

    printf("Received: %s\n", msg.mtext);

    // 删除消息队列
    if (msgctl(msqid, IPC_RMID, NULL) == -1) {
        perror("msgctl");
        exit(1);
    }

    return 0;
}

编译与运行 ⚙️

  1. 编译

    gcc sender.c -o sender
    gcc receiver.c -o receiver
    
  2. 运行

    • 先运行 发送端

      ./sender
      
    • 再运行 接收端

      ./receiver
      

关键注意事项 ⚠️

  1. 权限问题:确保 msgget 的权限标志(如 0666)允许进程访问队列。

  2. 消息类型mtype 必须为正整数,用于区分不同类型的消息。

  3. 队列持久性:即使进程退出,消息队列仍会保留,需显式调用 msgctl(IPC_RMID) 删除。

  4. 错误处理:所有 API 调用后应检查返回值,避免资源泄漏。


通过消息队列,可以实现 可靠的进程间通信,特别适用于生产者和消费者速度不匹配的场景。🚀

相关文章:

  • AIGC2——AI生成艺术的边界与伦理:艺术性、版权与美学价值的争议
  • 学习海康VisionMaster之多直线查找
  • 使用python访问mindie部署的vl多模态模型
  • 【数据结构】二叉搜索树
  • Android Input——输入子系统(三)
  • C++ Primer Plus 编程练习题 第六章 分支语句和逻辑运算符
  • 544 eff.c:1761处loop vect 分析
  • C++ 基本语法
  • C#/.NET/.NET Core技术前沿周刊 | 第 33 期(2025年4.1-4.6)
  • 【动态规划】 深入动态规划 回文子串问题
  • 浅谈Apache
  • 汉得企业级 PaaS 平台 H-ZERO 1.12.0 发布!四大维度升级,构建企业数字化新底座
  • STL c++ list——模拟实现
  • vue.config.js配置代理(输出代理前后的地址)
  • EG8200Mini-104边缘计算网关!聚焦IEC104协议的工业数据转换与远程运维平台
  • 【锂电池SOH预测】PSO-BP锂电池健康状态预测,锂电池SOH预测(Matlab完整源码和数据)
  • 数据链路层以太网协议
  • XYCTF2025 web 全wp
  • 【C++】stack和queue
  • Linux平台搭建MQTT测试环境
  • 落实中美经贸高层会谈重要共识,中方调整对美加征关税措施
  • 真人秀《幸存者》百万美元奖金,25年间“缩水”近一半
  • 80后莆田市文旅局长马骏登台与杨宗纬合唱,“演唱会秒变旅游推介会”
  • 4月国产新能源,降价潮迈入拐点
  • 成都锦江区一在建工地起火,致2人遇难1人受伤
  • 气象干旱黄色预警继续:陕西西南部、河南西南部等地特旱