Linux进程通信之消息队列

本文介绍了Linux中消息队列的原理,如何通过ftok创建索引并使用msgget、msgsnd和msgrcv API进行消息传递,通过示例展示了两个进程间的通信过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消息队列

这一节,我们讲进程通信的又一种方式,消息队列。

什么是消息队列?

消息队列是消息的链表,存放在内核中并由消息队列标识符表示。
  消息队列提供了一个从一个进程向另一个进程发送数据块的方法,每个数据块都可以被认为是有一个类型,接受者接受的数据块可以有不同的类型。
  简单用一张图理解:
  在这里插入图片描述
可以看到,在两个进程之间,可以用之前讲过的两种管道方式通信:一种亲缘关系进程,一种不是亲缘关系进程。
而消息队列由内核管理,就像一个一的链表一样,有自己的id号,通过key键值索引找到,进程A插入一个新的节点,将传入的消息写入进去插入后,B进程访问这个队列从而读出消息。(可以这样简单理解,可能说的不专业,但应该更好理解把。)

还要来看一看和键值key相关的ftok函数。

系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
ftok原型如下:
key_t ftok( char * fname, int id )

fname就时你指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。

当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。
简单来说,ftok创建一个key值,也可以是创建一个通讯的索引,这个索引可以作为消息队列的队列。

然后,来看看几个要用到的api,

1.msgget 创建队列
int msgget(key_t key,int flag);
key:索引值
flag:打开队列的方式,一般为IPC_CREAT
int型为队列的ID
成功返回队列ID,失败返回-1

2.msgsnd 发送消息
int msgsnd(int msgid(队列id),指针类型(消息),消息的大小,falg(标志位))
成功返回队列ID,失败返回-1

3.msgrcv 读取消息
int msgrcv(int msgid(队列id),消息的大小,type消息的类型,falg(标志位))

4.msgctl对消息队列进行操作
int msgctl(int msgid(队列id),int cmd,buf);

好,我们仍然是用两个进程来测试:
send.c发送消息的进程
在这里插入图片描述

get.c接收消息的进程

在这里插入图片描述# 思路讲解:
首先,在get进程中,
1.写一个消息队列的结构体,(这个样式是Linux提供的样板,可以就这样用),
2.创建一个用来插入消息队列的结点(结构体)。
3.索引一个消息队列,键值通过ftok函数获得,通过msgrcv函数获取这个消息队列的内容。
4.在内核中除去这个队列,以免过多消息队列出现。

在send进程中
1.写一个消息队列的结构体,(这个样式是Linux提供的样板,可以就这样用),
2.创建一个用来插入消息队列的结点(结构体)。
3.索引一个消息队列,键值通过ftok函数获得,通过msgrcv函数获取这个消息队列的内容。
4.实例化一个结构体,把要写入的信息写进去结构体的成员mtext中去,把这个结构体写入消息队列。

运行get后,消息队列中没有能够读取到的东西,会堵塞,直到send内容后才能读取到东西。
来看看运行结果:

运行结果:
在这里插入图片描述在这里插入图片描述可以看到,get从消息队列中读取到了写入的话,实现了进程间的通信。

(师上官可编程)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值