C语言中消息队列实现
消息队列的实现包含了System V
和POSIX
两种版本,在接口上有一定的差异。
POSIX消息队列
POSIX消息队列对应的头文件为mqueue.h
。
#include <mqueue.h>
建立:mq_open()
mq_open()
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <mqueue.h>
mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
参数
name
:符合命名规则的消息队列名称。oflag
:代表打开的方式(读写模式等),以O_的形式给出。mode
和attr
:可选,只有在oflag中含有O_CREAT标志且消息队列不存在时才需要。 *返回:所创建的消息队列(定义为mqd_t
类型)。oflag 以下为部分常用定义,详见Linux manual中的详细解释。
参数
操作
O_RDONLY
只读
O_WRONLY
只写
O_RDWR
可读可写
消息队列的属性:mq_getattr()
和mq_setattr()
mq_getattr()
和mq_setattr()
在Linux 2.6.18中,消息队列的属性被定义成如下结构体:
struct mq_attr
{
long int mq_flags; /* Message queue flags. */
long int mq_maxmsg; /* Maximum number of messages. */
long int mq_msgsize; /* Maximum message size. */
long int mq_curmsgs; /* Number of messages currently queued. */
long int __pad[4];
};
对于属性的获取和设置可以通过下列两个函数完成:
#include <mqueue.h>
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
int mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr);
说明
mq_setattr
唯一可以更改的属性是mq_flags
,用于设置或清除消息队列的阻塞标志。其他的的值都不可以设置,会被忽略。mq_maxmsg
和mq_msgsize
是在上面打开消息队列的时候设置的,队列创建后就不应该更改。而mq_curmsgs
指示了消息数量,是随着运行自动变化的,也不应该被设置。 返回值:均为成功返回0,否则返回-1。
发送消息:mq_send()
mq_send()
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
参数
mqdes
:之前使用mq_open()
建立的消息队列描述符。msg_ptr
:指向消息体缓冲区的指针。msg_len
:消息长度,不大于消息队列的mq_msgsize
属性值(不然发送出去的消息可能存不下)。msg_prio
:消息的优先级,不大于最大优先级MQ_PRIO_MAX
。
接收消息:mq_receive()
mq_receive()
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
参数
mag_len
不能小于属性中的mq_msgsize
,不然消息可能存不下。 其余的参数和mq_send()
一致。 优先级PISIX
消息队列始终返回优先级最高、最早的消息,不在接收时指定优先级。
消息队列的限制
消息队列可以占用的存储空间被系统所限制,在到达一定容量后将无法发送消息。 如果设置消息队列属性时,将消息数和消息长度设置过大,会导致消息队列创建失败。
相关限制可以在shell中修改:
~$ ulimit -q 1024000000
~$ ulimit -a |grep message
POSIX message queues (bytes, -q) 1024000000
另外还有MQ_OPEN_MAX
限制单个进程能同时打开的消息队列数(PISIX
保证至少为8),MQ_PRIO_MAX
限制最大优先级。
Last updated
Was this helpful?