7.2 POSIX 消息队列

POSIX 消息队列允许进程之间以消息的形式交换数据。

打开、关闭和断开消息队列

创建或打开一个消息队列:

#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

/*
@param name 	消息队列标识,一般为以 / 开头的字符串
@param oflag	可取:
            	- O_CREAT 	 不存在时创建
                - O_EXCL	 与 O_CREAT 搭配使用,排它地创建队列
                - O_RDONLY	 只读打开
                - O_WRONLY	 只写打开
                - O_RDWR	 读写打开
                - O_NONCLOCK 非阻塞模式打开
@param mode	与 attr 在指定 O_CREAT 创建消息队列时使用
            	mode 为位掩码指定了新消息队列上的权限,与文件权限一致
@param attr	指定消息队列的特性,一般指定为 NULL 采用默认特性

@return	返回消息队列描述符,失败返回 -1

*/
mqd_t mq_open(const char *name, int oflag, ...
              /* mode_t mode, struct mq_attr *attr */);

关闭一个消息队列:

此调用将关闭消息队列描述符,进程在不使用消息队列时应该关闭,放置出现进程耗尽消息队列描述符的情况。mq_close 并不会删除该队列。 删除一个消息队列:

mq_unlink 函数删除通过 name 标识的消息队列,并将队列标记为在所有进程使用完该队列之后销毁该队列(这可能意味着会立即删除,前提是所有打开该队列的进程已经关闭了该队列)。

消息队列特性

mq_open 中的 attr 可以指定新创建的消息队列的特性,它是一个 mq_attr 结构变量,定义如下:

其中 mq_maxmsg 和 mq_msgsize 在消息队列创建时就确定下来,之后便无法改变。系统也会对这两个特性有一个限制。 获取消息队列特性:

修改消息队列特性:

SUSv3 规定使用 mq_setattr 唯一可以修改的特性就是 O_NONBLOCK 的状态。

交换消息

发送一个消息:

如果消息队列已经满了,那么后续的 mq_send 调用会阻塞直到队列存在可用空间。或者开启了 O_NONBLOCK 标记,会立即返失败并返回 EAGIN 错误。 接收一个消息:

如果消息队列当前为空,那么 mq_receive 会阻塞直到存在可用的消息或在 O_NONBLOCK 标记起作用时会立即失败并返回 EAGAIN 错误。

与 System V 消息队列比较

POSIX 消息队列具备的优势:

  • 具有消息通知特性,允许消息进入一个空队列时通过信号或者线程函数异步通知(消息通知这里没有做介绍)。

  • Linux 上可以使用 poll、select、epoll 来监控 POSIX 消息队列,System V 则没有。

有以下劣势:

  • 可移植性较差,Linux 内核 2.6.6 之后提供了对消息队列的支持。

  • System V 消息队列可以根据类型来选择消息,更加灵活。

最后更新于

这有帮助吗?