linux中posix消息队列的使用记录

在linux中使用posix中的消息队列时遇到了一个问题,就是在发送消息时,如果队列满了,mq_send接口会一直阻塞,经过查找资料后才发现,该接口默认是阻塞的,也就是说,当队列满了以后,接口会一直等待,一直等到队列中有空间后才返回。

避免阻塞的方式有以下几种:

1、设置为非阻塞模式

在打开队列时,设置指定为O_NONBLOCK的标志,如下所示:

cpp 复制代码
mqd_t mq = mq_open("/myqueue", O_WRONLY | O_CREAT | O_NONBLOCK, 0644, &attr);

如果队列满了,该接口会立即返回-1,errno=11,也就是EAGAIN;

我使用的就是这种方式;

2、使用超时返送函数mq_timedsend(),参考代码如下所示:

cpp 复制代码
#include <mqueue.h>
#include <time.h>

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);  // 获取当前时间
ts.tv_sec += 5;  // 设置 5 秒超时

int ret = mq_timedsend(mq, msg_ptr, msg_len, msg_prio, &ts);
if (ret == -1) {
    if (errno == ETIMEDOUT) { /* 处理超时 */ }
}

注意,这个接口中的时间是系统绝对时间,表示相对时间,所以需要先获取当前的系统时间,再加上超时的时间;

这种方式我没有使用,是deepseek提供的方式;

3、增加消息队列容量

这种方式不解决根本问题,队列满了,依然是阻塞;

有一点儿需要注意,posix的消息队列时系统级的,如果队列满了,也没有消费者去读取队列里面的数据,这个时候,只能重启系统,才能将队列数据清空;