【原理剖析】4-进程间通信方式之消息队列
概述:知识点
- Linux 消息队列方式原理介绍
- Linux 消息队列相关 API 介绍
0x01 Linux 消息队列
消息队列 (也叫做报文队列)是 Unix 系统 V 版本中 3 种进程间通信机制之一。另外两种是信号量和共享内存。这些 IPC 机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源。这种系统 IPC 对象使用的控制方法和文件系统非常类似。使用对象的引用标志符作为资源表中的索引。
消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。
Linux 采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。这种通信机制相对简单,但是应用程序使用起来就需要使用相对复杂的方式来应付了。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。
消息队列是随内核持续的并和进程相关,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构 (struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构 msg_ids 中中找到访问入口。
IPC 标识符:每一个 IPC 目标都有一个唯一的 IPC标识符 。这里所指的 IPC目标 是指一个单独的消息队列、一个信号量集或者一个共享的内存段。系统内核使用此标识符在系统内核中指明 IPC目标 。
IPC关键字 :想要获得唯一的标识符,则必须使用一个 IPC关键字 。客户端进程和服务器端进程必须双方都同意此关键字。这是建立一个客户机/服务器框架的第一步。在 System V IPC 机制中,建立两端联系的路由方法是和 IPC关键字 直接相关的。通过在应用程序中设置关键字值,每一次使用的关键字都可以是相同的。一般情况下,可以使用 ftok() 函数为客户端和服务器端产生关键字值。
0x02 Linux消息队列使用步骤
- 创建或打开消息队列。使用的函数是
msgget(),这里创建的消息队列的数量会受到系统消息队列数量的限制。 - 添加消息。使用的函数是
msgsnd(),它把消息添加到已打开的消息队列末尾。 - 读取消息。使用的函数是
msgrcv(),它把消息从消息队列中取走,与FIFO不同的是,这里可以取走指定的某一条消息。 - 控制消息队列。使用的函数是
msgctl(),它可以完成多项功能。
0x03 Linux消息队列相关 API 介绍
在 Linux 操作系统中,我们可以通过使用 msgget() 函数来创建和打开消息队列,具体描述如下:
1 | |
向已经被创建和打开的消息队列中发送数据,可以使用 msgsnd() 函数,具体描述如下:
1 | |
对于消息队列的接收,在程序中可以通过调用 msgrcv() 来进行读取数据,如下:
1 | |
除了上述 API 之外,还可以用 msgctl() 函数来对消息队列进行设置,具体如下:
1 | |