0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux下进程通讯消息队列

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-08-19 19:56 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Linux下进程通讯消息队列

 MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已。MQ 是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信

消息队列与 FIFO 很相似,都是一个队列结构,都可以有多个进程往队列里面写信息,多个进程从队列中读取信息。

1.查看消息队列命令

  1.查看消息队列:ipcs -q

[wbyq@wbyq ~]$ ipcs -q

--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息      
0xb8104ad9 1          wbyq       644        0            0           
0xd2350093 2          wbyq       666        208          2  

  2.查看消息队列限制信息:ipcs -lq

[wbyq@wbyq ~]$ ipcs -lq

---------- 消息限制 -----------
系统最大队列数量 = 32000
最大消息尺寸 (字节) = 8192
默认的队列最大尺寸 (字节) = 16384

  3.查看消息队列详细信息:ipcs -q -i

[wbyq@wbyq ~]$ ipcs -q -i 2

消息队列 msqid=2
uid=1000	gid=1000	cuid=1000	cgid=1000	模式=0666
cbytes=208	qbytes=16384	qnum=2	lspid=10177	lrpid=10175
发送时间=Thu Apr 28 11:56:08 2022  
接收时间=Thu Apr 28 11:56:08 2022  
更改时间=Thu Apr 28 11:49:04 2022  

  4.创建消息队列:ipcmk -Q

[wbyq@wbyq ~]$ ipcmk -Q
消息队列 id:4
[wbyq@wbyq ~]$ ipcs -q

--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息      
0xb8104ad9 1          wbyq       644        0            0           
0xd2350093 2          wbyq       666        208          2           
0x05ae2c01 4          wbyq       644        0            0        

5.删除信号量:ipcrm -q

[wbyq@wbyq ~]$ ipcrm -q 4
[wbyq@wbyq ~]$ ipcs -q
--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息      
0xb8104ad9 1          wbyq       644        0            0           
0xd2350093 2          wbyq       666        208          2    

2.相关函数

#include 
#include 
#include 
int msgget(key_t key, int msgflg);
函数功能:创建消息队列
形参:key 键值,ftok产生
     msgflg 标志 IPC_CREAT|0666
返回值:失败返回-1,成功返回msqid
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
函数功能: 将消息添加到队列中
形参:msqid msgget函数返回值
   msgp 消息内容数据,一般以结构体类型填充
      struct msgbuf {
            long mtype; /* 消息类型, 必须 > 0 */
            char mtext[1]; /消息数据/
            };
      注意:struct msgbuf必须自己重写,第一个参数long mtype必须指定,且>0,其他类型自定义
   msgsz 消息字节数,大小为:sizeof(struct msgbuf)-sizeof(mtype);
   msgflg 0当队列满时阻塞,直到消息写入成功
      IPC_NOWAIT 当队列满时不阻塞,立刻返回
      IPC_NOERROR 若发送的消息大于 size 字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。
返回值:成功返回0,失败返回-1;
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
函数功能:从队列中取出消息
形参:msqid msgget函数返回值
   msgp 存放读取到的消息内容
   msgsz 消息字节数,大小为:sizeof(struct msgbuf)-sizeof(mtype);
   msgtyp 消息类型:
       >0 接收对列中的第 1 个类型等于 msgtyp 的消息
       ==0 取出消息队列中的第一条消息
       <0 接收其类型小于或等于 msgtyp 绝对值的第 1 个最低类型消息
   msgflg 0 当队列空时阻塞,或者消息类型不匹配时阻塞
       IPC_NOWAIT 不阻塞,立刻返回
       IPC_NOERROR 若发送的消息大于 size 字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。
返回值:成功返回读取的字节数,失败返回-1;
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
函数功能:控制函数
形参:msqid msgget函数返回值
   cmd 通常为 IPC_RMID 表示删除消息队列。
当删除消息队列时,则buf填NULL即可;

3.示例

  (1)创建消息队列,添加消息到队列

#include 
#include 
#include 
#include 
#include 
#include 
#include 
struct msgbuf
{
	long mtype;//消息类型,必须>0
	int cnt;
	char buff[100];
};
int main(int argc,char *argv[])
{
	if(argc!=4)
	{
		printf("格式:./app <消息类型> <消息数据> <消息内容>\n");
		return 0;
	}
    key_t key=ftok("msgsnd.c", 1234);//生成键值
	if(key==-1)
	{
		printf("生成键值失败err=%s\n",strerror(errno));
		return 0;
	}
	printf("key=%#x\n",key);
	int msqid=msgget(key,IPC_CREAT|0666);//创建消息队列
	if(msqid==-1)
	{
		printf("创建消息队列失败err=%s\n",strerror(errno));
		return 0;
	}
	printf("msqid=%d\n",msqid);
	struct msgbuf msg;
	msg.mtype=atoi(argv[1]);//消息类型
	msg.cnt=atoi(argv[2]);//消息数据
	strcpy(msg.buff,argv[3]);//消息内容
	int msg_size=sizeof(msg)-sizeof(long);//消息大小,总大小-消息类型大小
	/*添加消息到队列*/
	int size=msgsnd(msqid,&msg,msg_size,0);
	if(size==-1)
	{
		printf("写入消息失败err=%s\n",strerror(errno));
	}
	else printf("消息写入成功\n");
	return 0;
}  

  (2)从队列中取消息

#include 
#include 
#include 
#include 
#include 
#include 
#include 
struct msgbuf
{
	long mtype;//消息类型,必须>0
	int cnt;
	char buff[100];
};
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("格式:./app <消息类型>\n");
		return 0;
	}
    key_t key=ftok("msgsnd.c", 1234);//生成键值
	if(key==-1)
	{
		printf("生成键值失败err=%s\n",strerror(errno));
		return 0;
	}
	printf("key=%#x\n",key);
	int msqid=msgget(key,IPC_CREAT|0666);//创建消息队列
	if(msqid==-1)
	{
		printf("创建消息队列失败err=%s\n",strerror(errno));
		return 0;
	}
	printf("msqid=%d\n",msqid);
	struct msgbuf msg;
	int msg_size=sizeof(msg)-sizeof(long);//消息大小
	long msgtyp=atoi(argv[1]);//要写读取的消息类型
	//从消息队列中取数据
	ssize_t size=msgrcv(msqid,&msg,msg_size,msgtyp,0);
	if(size==-1)
	{
		printf("读取消息失败err=%s\n",strerror(errno));
	}
	else 
	{
		printf("------------读取消息成功size:%ld----------------\n",size);
		printf("\tmtype=%ld\n",msg.mtype);
		printf("\tcnt=%d\n",msg.cnt);
		printf("\tbuff=%s\n",msg.buff);
	}
	return 0;
}  

  (3)运行效果

pYYBAGL_eXuABxWmAAeJ5O7XsAY981.png#pic_center


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11627

    浏览量

    217895
  • IPC
    IPC
    +关注

    关注

    3

    文章

    375

    浏览量

    54542
  • 进程
    +关注

    关注

    0

    文章

    208

    浏览量

    14477
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux进程间通信(IPC)全解析:从管道到 Socket,一篇讲透

    在 Linux 世界里,进程并非孤立存在。无论是后台服务协作(如 Web 服务器与数据库)、命令行工具联动(如ps | grep),还是复杂应用的模块通信,都离不开 进程间通信(IPC
    的头像 发表于 11-14 21:38 1.2w次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>间通信(IPC)全解析:从管道到 Socket,一篇讲透

    基于环形队列的UART收发回显实验

    在实际项目开发中,由于有些串口不具备FIFO(如SCI1和SCI2)或FIFO的buffer比较小,这可能会在数据处理速度小于数据接收速度的时候,导致数据的丢失。因此我们可以设计一个队列来避免这一
    的头像 发表于 10-27 13:51 1685次阅读
    基于环形<b class='flag-5'>队列</b>的UART收发回显实验

    【HZ-T536开发板免费体验】—— linux 进程创建

    Linux进程通信方式有这几种: 1。管道 2。信号量 3。消息队列 4。共享内存 在本帖子中,我会讲解fork(),exit()系统调用的实践。通过应用编程来实现系统调用。 1,进程
    发表于 09-01 20:49

    NVMe高速传输之摆脱XDMA设计十:队列管理模块设计(

    ​续上,队列管理模块采用队列的存储与控制分离的设计结构,如图1所示为队列管理模块的结构框图。 ​编辑 图1 队列管理结构 由于提交队列管理单
    发表于 07-30 16:27

    RabbitMQ消息队列解决方案

    在现代分布式系统架构中,消息队列作为核心组件,承担着系统解耦、异步处理、流量削峰等重要职责。RabbitMQ作为一款成熟的消息队列中间件,以其高可用性、高可靠性和丰富的特性,成为众多企业的首选方案。本文将从运维工程师的角度,详细阐述RabbitMQ从单机部署到集群搭建的完
    的头像 发表于 07-08 15:55 427次阅读

    NVME控制器之队列管理模块

    造成延迟较大的问题。本设计主要针对顺序读写场景进行了资源方面的优化。考虑到在顺序读写情况,传输性能与队列深度的大小无关,且硬件逻辑生成NVMe命令的速度要远大于软件协议栈生成NVMe命令的速度,因此
    发表于 05-03 20:19

    Linux常用命令大全

    Linux常用命令是指在Linux操作系统中广泛使用的命令工具,这些命令工具可以完成各种不同的任务,如管理文件和目录、操作进程、网络通信、软件安装等。
    的头像 发表于 05-03 18:08 1610次阅读

    NVME控制器之队列管理模块

    队列管理模块是整个NVMe Host控制器的核心模块,该模块实现了提交队列与完成队列的管理,多队列请求的仲裁判决等功能。队列管理模块中含有数
    的头像 发表于 05-03 15:32 420次阅读
    NVME控制器之<b class='flag-5'>队列</b>管理模块

    Linux后台进程管理详解

    当我们在终端或控制台工作时,可能不希望由于运行一个作业而占住了屏幕,因为可能还有更重要的事情要做,比如阅读电子邮件。对于密集访问磁盘的进程,我们更希望它能够在每天的非负荷高峰时间段运行(例如凌晨)。为了使这些进程能够在后台运行,也就是说不在终端屏幕上运行,有几种选择方法可
    的头像 发表于 04-25 11:04 796次阅读
    <b class='flag-5'>Linux</b>后台<b class='flag-5'>进程</b>管理详解

    Linux系统进程管理入门指南

    Linux 系统中,进程是正在运行的程序的实例。理解进程的管理、查看和控制对于系统管理员和开发者来说非常重要
    的头像 发表于 04-22 14:34 852次阅读
    <b class='flag-5'>Linux</b>系统<b class='flag-5'>进程</b>管理入门指南

    LinuxVim编辑器的使用技巧

    【Vim】常用总结⟳ 简介⟳ image 什么是vim?⟳ Linux两大编辑神器之一 vim • Linux/Unix使用最多的编辑器 • vi的改进版 • 可能是最难上手的编辑
    的头像 发表于 04-01 17:36 1024次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>下</b>Vim编辑器的使用技巧

    Linux进程状态详解

    进程状态是task_struct内的一个整数;进行:进程在调度队列中,进程的状态都是running,阻塞:等待某种设备或者资源就绪。进程是一
    的头像 发表于 04-01 09:46 804次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>状态详解

    中兴通讯亮相2025年世界移动通信大会

    近日,中兴通讯携全队列多形态AI终端亮相世界移动通信大会(MWC25巴塞罗那),为全球用户带来全场景AI体验。
    的头像 发表于 03-10 10:12 1133次阅读

    Linux计划任务cron详解

    cron是linux用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows的计划任务类似,当安装完成操作系统后,默认会安装此服务 工具,并且会自动启动crond
    的头像 发表于 02-07 15:31 1526次阅读
    <b class='flag-5'>Linux</b>计划任务cron详解

    深入解析Linux程序与进程

    什么是程序 一组计算机能识别和执行的指令,用于指导计算机执行特定任务或解决特定问题。程序通常由代码、数据和资源文件组成,涉及语法、算法和数据结构。为二进制文件 什么是进程 是一个具有独立功能的程序
    的头像 发表于 12-18 11:01 830次阅读
    深入解析<b class='flag-5'>Linux</b>程序与<b class='flag-5'>进程</b>