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)运行效果

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
Linux
+关注
关注
88文章
11893浏览量
220211 -
IPC
+关注
关注
3文章
387浏览量
55217 -
进程
+关注
关注
0文章
211浏览量
14589
发布评论请先 登录
相关推荐
热点推荐
飞凌嵌入式ElfBoard-进程间的通信
、消息队列、信号量、共享内存、和套接字等方式,每种机制适用于不同的场景。⚫信号:可以异步通信,并且具有轻量级的特点,但是不能传递复杂的数据,只能携带少量信息。⚫管道:普通管道只能在父子进程之间单向通信
发表于 05-14 08:56
飞凌嵌入式ElfBoard-进程之进程状态
在Linux系统中,进程状态对于系统调度、资源分配和管理非常重要,因为它表示了进程当前的执行状况和资源使用情况。在Linux 系统中使用ps -aux 命令可观察到
发表于 03-27 09:12
中兴通讯全队列多形态AI终端产品亮相MWC 2026
3月2日,在2026年世界移动大会(MWC26巴塞罗那)上,中兴通讯终端业务携全队列、多形态AI终端产品亮相。搭载豆包手机助手的AI原生手机努比亚M153豆包手机助手技术预览版迎来海外首秀,主打情感陪伴的AI“新物种”iMoochi也在本次展会发布。
飞凌嵌入式ElfBoard-进程之什么是进程
在Linux系统中,有些基本命令能够查看到进程的信息。例如ps、top、pgrep、pstree等;这些命令为用户提供了查看和管理Linux进程信息的多种功能。通过合理使用这些命令,用
发表于 03-02 08:49
Linux进程管理不用愁!这6个工具帮你搞定90%场景
在 Linux 系统中,进程是资源分配的基本单位,无论是服务器运维、程序调试还是日常使用,掌握进程管理工具都是必备技能。今天就带大家梳理 6 个最常用的进程管理工具,从查看
Linux进程树分析工具pstree详解与实战指南(另一视角优化Linux系统)
在 Linux 系统开发与运维中,理解进程的运行状态和相互关系是排查问题、优化性能的基础。pstree 作为一款轻量高效的进程树可视化工具,能直观展示系统中所有进程的父子关系,为系统分
深入Linux内核:进程调度的核心逻辑与实现细节
在Linux系统中,进程调度就像一位精明的“CPU管理员”——它决定着哪个进程能优先使用CPU,多久切换一次进程,如何平衡系统响应速度与资源利用率。小到桌面应用的流畅点击,大到服务器的
解析Linux的进程、线程和协程
)进程间通信(IPC):Linux提供了多种IPC机制,如管道、信号、共享内存和消息队列,用于进程之间的通信。
线程管理
在Linux中,线
发表于 12-22 11:00
Linux进程间通信(IPC)全解析:从管道到 Socket,一篇讲透
在 Linux 世界里,进程并非孤立存在。无论是后台服务协作(如 Web 服务器与数据库)、命令行工具联动(如ps | grep),还是复杂应用的模块通信,都离不开 进程间通信(IPC
基于环形队列的UART收发回显实验
在实际项目开发中,由于有些串口不具备FIFO(如SCI1和SCI2)或FIFO的buffer比较小,这可能会在数据处理速度小于数据接收速度的时候,导致数据的丢失。因此我们可以设计一个队列来避免这一
【HZ-T536开发板免费体验】—— linux 进程创建
Linux进程通信方式有这几种:
1。管道
2。信号量
3。消息队列
4。共享内存
在本帖子中,我会讲解fork(),exit()系统调用的实践。通过应用编程来实现系统调用。
1,进程
发表于 09-01 20:49
Linux下进程通讯消息队列
评论