关于Linux消息队列的简单说明、使用、编码

1. 消息队列的特点

消息队列是一种可以在两个不相关进程间传递数据的进程间通信系统。消息队列独立于发送和接收进程,发送方与接受方不需要同步。进程使用消息队列可以向其他进程传送数据块,每个数据块有一个最大尺寸的限制,同时在系统中所有消息队列的块尺寸也有一个最大尺寸的限制。Linux中有两个定义: MSGMAXMSGMNB,分别用于定义单个消息与一个队列的最大尺寸(我目前没找到这两个宏定义)。

2. 与消息队列相关的系统调用

序号 系统调用方式
1 创建或打开消息队列
2 获取和设置消息队列的属性
3 将消息送入消息队列
4 从消息队列中读取一条新消息
5 生成键值函数

2.1 创建或打开消息队列(msgget)

#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>int msgget(key_t key, int msgflg); // 用于得到一个已存在的消息队列标识符或创建一个消息队列对象
// key表示消息队列的键值,这个键值用于标识一个消息队列,可以自定义一个键值,或者使用ftok函数生成
// key如果取宏IPC_PRIVATE(0),表示创建一个私有队列,这个理论上只可以被当前进程所访问
// msgflg表示创建或者访问消息队列的具体方式,取值如下:
// IPC_CREAT(01000): 如果消息队列对象不存在,则创建之
// IPC_EXCL(02000): 如果消息队列对象存在,则报错
// msgflg往往使用多个值进行“或”操作来取值,至于原因,还需要专门探究,我目前创建消息队列时使用的msgflg值为:IPC_CREAT|06000
// 返回值:执行成功,则返回一个正数作为消息队列的标识符,其他操作消息队列的函数将会使用这个标识符;执行失败,返回-1。

2.2 获取和设置消息队列的属性(msgctl)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf); // 目前我只是知道这个函数可以用来释放消息队列,当实现这一功能时,buf可以为NULL
// msqid表示消息队列标识符,为msgget函数的有效返回值
// cmd表示要对消息队列进行的操作,取值可以是:
// IPC_STAT: 读取消息队列的msqid_ds数据,并将其存储在buf指定的地址中。
// IPC_SET: 设置消息队列的属性,要设置的属性需要先存储在buf中
// IPC_EMID: 将队列从系统内核中删除
// buf指向消息队列管理结构体msqid_ds,该结构定义我就先不写了。
// 返回值:0,执行成功

2.3 将消息送入消息队列(msgsnd)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// msqid为消息队列标识符
// msgp指向消息缓存区,通常可用一个通用结构表示消息
struct msgbuf
{long mtype; // 消息类型,这个值要大于0,数值自定义char mtext[SIZE]; // 消息数据,大小自定义 // 我没有尝试过将char类型改为其他类型
};
// msgsz是要发送信息的长度,大小为sizeof(mtext)
// msgflg是控制函数行为的标志, 0表示阻塞方式,IPC_NOWAIT表示非阻塞方式
// 执行成功返回0,执行失败返回-1

2.4 从消息队列中读取一条新消息(msgrcv)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msqid, const void *msgp, size_t msgsz, long msgtyp, int msgflg);
// msqid为消息队列标识符
// msgp指向消息缓存区,通常可用一个通用结构表示消息
// msgsz大小为sizeof(mtext)
// msgtyp表示从消息队列内读取的消息形态,0表示消息队列中所有消息都会被读取。
// msgflg是控制函数行为的标志, 0表示阻塞方式,IPC_NOWAIT表示非阻塞方式
// 执行成功返回0,执行失败返回-1

2.5 生成键值函数(ftok)

// 如2.1中所说,生成一个消息队列需要一个键值,这个键值可以自定义,也可以调用ftok函数来生成
key_t ftok(char *fname, int id);
// fname是指定的文件名,这个文件必须是存在且可以访问,并且一旦创建后就不能在删除(即使删除了后重新建一个同名文件也不行)
// id是子序号,范围0-255,大小自定义
// 执行成功返回key_t值,否则返回-1。这个函数我没有写示例代码。

3. 示例程序

// 接下来的实例程序展示了2.1~2.4的使用方式,包含两个程序,一个创建消息队列、发送消息后退出;一个打开消息队列,读取消息后删除消息队列,然后退出,以此来体
// 现消息队列的不需要同步读写进程、不限制读写进程关系的优点
// 写进程
#include <iostream>
#include <unistd.h>
#include <sys/msg.h>
#include <errno.h>
#include <memory.h>typedef struct MSG
{long i64Flag; // 用来标识传输数据的类型,自定义char arrText[10]; // 发送数据
}MSG;int main()
{int i32Ret = 0; int i32msgid = 0;i32msgid = msgget((key_t)(1234), IPC_CREAT|666); // 创建消息队列if (0 > i32msgid){std::cout << "消息队列创建失败" << errno << std::endl;return EXIT_FAILURE;}// 编辑要发送的数据int i32Num = 5;char arrText[4] = "end";MSG stMsg1, stMsg2;stMsg1.i64Flag = 1;memcpy(stMsg1.arrText, &i32Num, sizeof(i32Num));stMsg2.i64Flag = 2;memcpy(stMsg2.arrText, arrText, sizeof(arrText));i32Ret  = msgsnd(i32msgid, (void*)(&stMsg1.i64Flag), sizeof(stMsg1.arrText), 0);i32Ret |= msgsnd(i32msgid, (void*)(&stMsg2.i64Flag), sizeof(stMsg2.arrText), 0);if (EXIT_SUCCESS == i32Ret){std::cout << "发送成功" << std::endl;}else{std::cout << "发送失败" << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;
}
// 读进程
#include <iostream>
#include <unistd.h>
#include <sys/msg.h>
#include <memory.h>
#include <errno.h>typedef struct MSG
{long i64Flag; // 用来标识传输数据的类型,自定义char arrText[10]; // 发送数据
}MSG;int main()
{int i32Ret = 0; int i32msgid = 0;i32msgid = msgget((key_t)(1234), IPC_CREAT|666); // 获取消息队列if (0 > i32msgid){std::cout << "消息队列获取失败" << std::endl;return EXIT_FAILURE;}// 创建获取消息的数据结构MSG stMsgRev;while(1){memset(&stMsgRev, 0, sizeof(stMsgRev));i32Ret = msgrcv(i32msgid, (void*)(&stMsgRev.i64Flag), sizeof(stMsgRev.arrText), 0, 0);if(1 == stMsgRev.i64Flag){// 接受到的数据为数字数组std::cout << stMsgRev.arrText << std::endl; // 这里接受到的不是我发送的数字,而是0x7ffd1da7a098,目前还不知道是什么原因std::cout << (int*)(&stMsgRev.arrText) << std::endl;}else{// 接受的到数据为字符串std::cout << stMsgRev.arrText << std::endl;char arr[4] = "end";if (0 == memcmp(stMsgRev.arrText, arr, 4)){i32Ret = msgctl(i32msgid, IPC_RMID, NULL);if (0 == i32Ret){std::cout << "消息队列删除成功" << std::endl;}break;}}}return EXIT_SUCCESS;
}

关于Linux消息队列的简单说明、使用、编码相关推荐

  1. linux.调整收发队列,linux消息队列通信

    程序目的:学习linux消息队列通信 所用主要函数:msgget(),msgsnd(),msgrcv(),msgctl() 首先介绍每个函数的用法: (1)msgget 使用格式: #include ...

  2. linux消息队列非亲缘,linux进程

    linux进程Tag内容描述: 1.linux消息队列进程通信 一.消息队列的基本概念消息队列(也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一.另外两种是信号灯和共享内存.这些IPC机制 ...

  3. linux 消息队列 msgget/msgsnd/msgrecv

    专栏内容:linux下并发编程 个人主页:我的主页 座右铭:天行健,君子以自强不息:地势坤,君子以厚德载物. 目录 前言 概述 原理 消息队列的大小 查看资源 接口 代码演示 结尾 前言 本专栏主要分 ...

  4. Linux消息队列编程(简单应用)

    消息队列,Unix的通信机制之一,可以理解为是一个存放消息(数据)容器.将消息写入消息队列,然后再从消息队列中取消息,一般来说是先进先出的顺序.可以解决两个进程的读写速度不同(处理数据速度不同),系统 ...

  5. 设计两个程序要求用消息队列实现简单的聊天功能linux,linux软件工程师(C语言)实用教程第7章.ppt...

    第7章 进程间的通信 2 本章重点 进程通信中信号概念及信号处理进程间的管道通信编程进程间的内存共享编程 3 7 1 1信号及其使用 信号是在软件层次上对中断机制的一种模拟 是一种异步通信方式 信号可 ...

  6. 设计两个程序要求用消息队列实现简单的聊天功能linux,Linux C 消息队列实现简单的聊天功能...

    消息队列是提供一种带有数据标识的特殊管道,使得每一段被写入的数据都变成带标识的消息,读取该段消息的进程只要指定这个标识就可以正确地读取,而不会受到其他消息的干扰,.一个带标识的消息队列,就像并存的管道 ...

  7. linux 消息队列机制

    现在我们来讨论第三种也是最后一种System V IPV工具:消息队列.在许多方面看来,消息队列类似于有名管道,但是却没有与打开与关闭管道的复杂关联.然而,使用消息队列并没有解决我们使用有名管道所遇到 ...

  8. linux 消息队列_Linux消息队列

    消息队列,Unix的通信机制之一,可以理解为是一个存放消息(数据)容器.将消息写入消息队列,然后再从消息队列中取消息,一般来说是先进先出的顺序.可以解决两个进程的读写速度不同(处理数据速度不同),系统 ...

  9. Linux消息队列原理与应用

    消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一.另外两种是信号灯和共享内存.这些IPC机制使用共同的授权方法.只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源.这 ...

  10. 消息队列--RabbitMQ简单使用

    安装使用 地址:http://www.rabbitmq.com/ 需要根据不同的版本选择不同的erlang 安装erlang 安装RabbitMQ首先需要安装erlang环境,根据GitHub上erl ...

最新文章

  1. mysql 错误1930xc1_Mysql写入记录出现 Incorrect string value: '\xB4\xE7\xB1\xCA\xBC\xC7‘错误?(写入中文)...
  2. Mockito cannot mock/spy because : - final class 问题
  3. Python中flatten( ),matrix.A用法
  4. VueI18n的应用
  5. Vue基本操作及运行截图总结
  6. 黑客瞄准美国 ATM 机,疯狂窃取超百万美元资金
  7. java打字训练课程设计_Java打字训练课程设计
  8. MYsql源码及其剖析
  9. java排序之选择排序
  10. 某公司的雇员分为以下若干类: Employee:这是所有员工总的父类.属性:员工的姓名,员工的生日月份。 方法:getSalary(intmonth)
  11. 计算机电子表操作格试题,计算机电子表格试题含答案Excel
  12. 【易通慧谷】供应链金融六大模式解析
  13. 小学计算机基础知识思维导图,简单易懂的小学除法思维导图
  14. 51单片机——串口通信详解(STC89C51为例)
  15. godaddy php5.ini,Godaddy主机修改上传文件限制
  16. 《大数据项目实战之搜索引擎用户行为分析》
  17. zarchiver解压提示出错_zarchiver解压操作出错怎么办 zarchiver解压操作出错解决办法...
  18. Kali+Win7双系统
  19. 鸿蒙os2.0第一批升级名单,首批升级鸿蒙OS名单终于来了!
  20. Linux基础命令学习——实战篇(给swap分区增加500M)

热门文章

  1. 如何快速进入/打开cmd--快捷键
  2. 39份AICon全球人工智能与机器学习技术大会 · 北京站2021(PPT汇总)
  3. 经典laravel后台管理系统
  4. 华为给出的测试账号里面的题
  5. 如何在和010editor中粘贴hex
  6. python分离gif_python 将GIF拆分成图片方法
  7. 考研高等数学张宇30讲笔记——第一讲 高等数学预备知识
  8. python实现爬取网页将特定信息存入excel
  9. 修改Android 模拟器IMEI
  10. pem加密php,PHP格式化RSA公钥私钥(pem文件)