1. SystemV消息队列简介

消息队列,顾名思义即是存放消息的队列,内核为每个SystemV 维护了一个msg_queue的结构体,里面记录了每个消息队列的信息。

struct msg_queue {structkern_ipc_perm q_perm;   // 权限相关time_tq_stime;         /* 上一次 msgsnd时间 */time_tq_rtime;         /* 上一次 msgrcv时间 */time_tq_ctime;         /* 属性变化时间 */unsignedlong q_cbytes;     /* 队列当前字节总数 */unsignedlong q_qnum;       /* 队列当前消息总数 */unsignedlong q_qbytes;     /* 一个消息队列允许最大字节数 */pid_tq_lspid;          /* 上一个调用msgsnd的进程ID */pid_tq_lrpid;          /* 上一个调用msgrcv的进程ID */structlist_head q_messages;structlist_head q_receivers;structlist_head q_senders;
};                                                                                                                                                         

消息队列存储消息的结构体需要用户自定义,且第一个字段必须是long类型。虽然诞生已久,但是systemV支持优先级队列和FIFO这一点确实是挺强大的,缺点也很明显,不支持IO多路复用。一般大型的MQ开发很少用到SystemV mq,因为存在很多限制,比如系统能够创建的消息队列个数有限,单条消息大小受限,单个消息队列里面消息个数受限等等。即便如此还是需要学习一下systemV消息队列,以后自己做相关的开发可以借鉴相关的设计思路。

2. API接口

2. 1 创建或获取消息队列ID

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>/**
* @brief 创建或获取消息队列ID
*
* @params key 标识符,整形变量,三种方式,固定值,IPC_PRIVATE,ftok生成
* @params msgflg,标志位,IPC_CREAT and IPC_EXCL
*
* @returns 成功返回消息队列ID,失败返回-1
*/int msgget(key_t key, int msgflg);

2.2 写消息

/**
* @brief 发送消息
*
* @params msqid 消息队列ID
* @params msgp 待发送消息的地址,类型需要自定义且第一个元素为long类型
* @params msgsz 消息大小
* @params msgflg 标志位,IPC_NOWAIT,未指定情况下,如果消息队列空间满,默认阻塞,设置此标志位则立即返回。* @returns 成功返回消息队列ID,失败返回-1
*/int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

2.3 读消息

/**
* @brief 发送消息
*
* @params msqid 消息队列ID
* @params msgp 接收消息的缓存,需要和发送方约定好结构体
* @params msgsz 接收消息最大长度,不包括消息类型字段
* @params msgtyp 要接收的消息类型。
>0分为两种情况,如果设置了MSG_EXCEPT,从消息队列中取出第一条消息类型相同的消息。
否则,取出第一条消息类型不同的消息。
=0相当于先入先出,最早进入消息队列的消息被取出。
<0相当于优先级队列,取出值小于或等于msgtyp绝对值的第一条消息* @params msgflg 标志位,IPC_NOWAIT,MSG_EXCEPT,MSG_NOERROR(消息过长时是否截断)* @returns 成功返回接收到的消息内容长度,失败返回-1
*/ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

2.4 消息队列其它控制操作

/**
* @brief 控制操作
*
* @params msqid 消息队列ID
* @params cmd 控制命令类型
IPC_STAT 获取或设置消息队列的属性
IPC_SET  设置权限相关属性
IPC_RMID 删除消息队列,释放消息队列中的所有消息* @returns 成功返回0,失败返回-1
*/int msgctl(int msqid, int cmd, struct msqid_ds *buf);

3. 示例

下面是一个简单的消息队列例子,分为读消息和写消息两个部分。

3.1读取


// 读取消息队列#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <string.h>// 消息结构体,第一个元素必须是消息类型
struct msg{long mtype;         // 消息类型char data[1024];    // 数据
};int main()
{int mq_id = 0;key_t key = 1357;       // 标识符,三种方式,固定值,IPC_PRIVATE,ftok生成ssize_t msg_size;struct msg message={0};// 创建或获取消息队列mq_id = msgget(key, IPC_CREAT);if (mq_id == -1){printf("create mq error");return mq_id;}// 循环监听消息队列while (1){// 阻塞监听所有消息类型的消息msg_size = msgrcv(mq_id, (void *)&message, sizeof(message), 0, 0);    if (msg_size != -1){printf("read msg type:%ld, data:%s\n", message.mtype, message.data);}memset(&message,0,sizeof(message));}return 0;
}

3.2 写入

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>// 消息结构体,第一个元素必须是消息类型
struct msg{long mtype;         // 消息类型char data[1024];    // 数据
};int main(int argc, char** argv)
{if (argc < 3){printf("invalid param, please input msg type and data\n");printf("Usage: ./mq_write type data\n");return -1;}int mq_id = 0;key_t key = 1357;       // 标识符,三种方式,固定值,IPC_PRIVATE,ftok生成// 创建或获取消息队列mq_id = msgget(key, IPC_CREAT);if (mq_id == -1){printf("create mq error\n");return mq_id;}struct msg message;message.mtype = strtol(argv[1],NULL,0);strcpy(message.data, argv[2]);// 发送消息if (msgsnd(mq_id, (const void*)&message, sizeof(message), 0) == 0){printf("send message succ\n");}else{printf("send message error\n");}return 0;
}

3.3 编译&运行

gcc -o mq_read mq_read.c
gcc -o mq_wirte mq_write.c

4. 注意事项

4.1  消息队列限制

MSGMAX 单条消息大小有限
cat /proc/sys/kernel/msgmaxMSGMNI 消息队列总个数有限
cat /proc/sys/kernel/msgmniMSGMNB 单个消息队列最大大小
cat /proc/sys/kernel/msgmnb

5. 参考资料

1. https://man7.org/linux/man-pages/man2/msgsnd.2.html

2. 《Linux环境编程 从应用到内核》

3. 《Unix网络编程 卷二 进程间通信》

================================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。...

Linux进程间通信二 System V 消息队列简介与示例相关推荐

  1. linux进程间通信:system V消息队列

    文章目录 基本介绍 编程接口 代码实例 消息队列的发送和接收 消息队列中的消息对象的属性控制 基本介绍 支持不同进程之间以消息(messages)的形式进行数据交换,消息能够拥有自己的标识,且内核使用 ...

  2. Linux进程间通信一 System V 共享内存简介与示例

    目录 1. System V共享内存简介 2. API介绍 2.0 key_t和标识符 2.1  创建system v共享内存 2.2 映射共享内存并使用 2.3 取消共享内存映射 2.4 控制共享内 ...

  3. Linux进程通信之System V消息队列

    System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...

  4. 细说linux IPC(十):system V 消息队列

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] system V消息队列和posix消息队列类 ...

  5. 【Linux】system V 消息队列 | system V 信号量(简单赘述)

    文章目录 1 . system V 消息队列(了解) 接口 查看消息队列 2.system V 信号量 (了解) 1.进程互斥等概念的理解 2.认识信号量 3. 接口 这两部分主要是了解即可,为后面学 ...

  6. Linux网络编程之System V消息队列

    System V消息队列函数: #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> int ...

  7. System V 消息队列

    一.System V 消息队列 有一个队列,队列存放各种消息.每个进程可以把数据封存在消息中,再放入队列.每个进程都可以拿到消息队列,再从中取出/放入消息. 消息队列也有管道一样的不足,就是每个消息的 ...

  8. System V消息队列

    简介 这篇笔记中介绍了消息队列的基本知识和Posix消息队列.这篇笔记主要学习记录System V消息队列,并对比两个消息队列. System V消息队列是更早的一个消息队列的实现.Posix消息队列 ...

  9. System V 消息队列概念以及相关函数(msgget、msgsnd、msgrcv、msgctl)介绍

    System V 消息队列 消息队列是半双工的通信方式 1.1 创建一个消息队列 消息队列的特点:消息只能一条的读取,不能多读取,也不能少读取,每条消息有一个类型,可以按照消息的类型读取 创建或者打开 ...

最新文章

  1. tcpdump 命令的个常用选项:一
  2. Linux 内核代码行数达到 2700 万行量级
  3. 真·摸鱼带师!每天工作10分钟年薪57万,这位程序员火了
  4. 计算机二级msoffice操作题如何评分,2017年计算机二级MSOffice操作题及答案解析
  5. spring bean中scope=prototype“的作用
  6. 【编译原理】编译是怎么一个过程?
  7. Fibinary Numbers
  8. 记一次MySQL手工注入
  9. 计算机语言中tc是什么,新人必须了解的几个TC常用语和脚本基础知识!
  10. Xilinx FPGA芯片命名规则
  11. 检查容器内的磁盘占用shell(check_container_disk.sh)
  12. 2011-4-1 live the lie until the lie becomes your life
  13. MATLAB免疫算法与粒子群算法进行函数优化
  14. CAD如何打印出多页PDF保存在一个PDF内
  15. Workbench中直接调用ICEM CFD进行网格划分
  16. 缠中说禅形态挖掘之七笔形态
  17. 如何用决策树模型做数据分析?
  18. 探究雷达(RADAR)工作原理
  19. Android中Gson使用,flutter调用原生sdk
  20. [英语阅读]希腊古剧场对高跟鞋说“不”

热门文章

  1. ABP理论学习之开篇介绍
  2. 复原所有面板设置+剪切板
  3. GeoServer 数据导出
  4. Get Start from today
  5. python 服务端渲染_客户端渲染和服务器渲染的区别
  6. python2 与 python3 语法区别
  7. img 隐藏_CSS3界面样式和溢出文字隐藏overflow
  8. 【控制】《多智能体系统一致性与复杂网络同步控制》郭凌老师-第3章-具有扩散作用的多智能体系统领导-跟随一致性
  9. 【数理知识】《矩阵论》方保镕老师-目录及关于符号的含义
  10. 2.10 局部最优的问题-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授