【原理剖析】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 |
|