【问题标题】:How to clear a POSIX Message Queue?如何清除 POSIX 消息队列?
【发布时间】:2016-06-03 13:25:55
【问题描述】:

我目前正在开发一个通过 Posix 消息队列进行 IPC 的程序。我现在需要一个函数来删除该队列的每条消息。问题是:我的代码死锁。目前我正在尝试以下方法:

void clear_mq(std::string queue_name)
{
    struct mq_attr mq_attrs = {0, 10, sizeof(uint8_t), 0};

    mqd_t mq = ::mq_open(queue_name.c_str(), O_WRONLY | O_CREAT, 00644, &mq_attrs);

    if (mq < 0)
    {
        std::cout << "Error opening Queue" << std::endl;
        exit(-1);
    }

    struct mq_attr num_messages;
    if (mq_getattr(mq, &num_messages) == -1)
    {
        std::cout << "Error!" << std::endl;
        exit(-1);
    }
    while (num_messages.mq_curmsgs > 0)
    {
        uint8_t buf;
        mq_receive(mq, (char *)&buf, sizeof(uint8_t), NULL);
        if (mq_getattr(mq, &num_messages) == -1)
        {
            std::cout << "Error!" << std::endl;
            exit(-1);
        }
    }
    mq_close(mq);
}

谁能指出我做错了什么?我不明白为什么接收被阻塞......在我打电话给clear_mq的那一刻,没有其他人在接收块......

【问题讨论】:

    标签: c++ posix message-queue


    【解决方案1】:

    恕我直言,您没有僵局。但是,mq_receive 会阻塞,直到它收到消息 (man mq_receive),因为在 mq_open 时队列未使用 O_NONBLOCK 参数打开。

    还请确保不要忽略循环中mq_receive 的返回值。

    【讨论】:

    • 是的,但我确保它只在消息可用时才进入mq_receive 调用(通过mq_getattr)。结果很好,谢谢!
    【解决方案2】:

    可能是mq_receive() 失败了,你最终陷入了无限循环。

    mq_receive() 可能因各种原因失败,例如提供的缓冲区必须至少具有mq-maxsize 的大小。

    您应该检查 mq_receive() 的返回值,如果失败则退出循环。

    【讨论】:

      【解决方案3】:

      万一其他人有问题。

      打印errno 时出现错误9(错误的文件描述符),这是有道理的,因为消息队列只为写入而打开,但您正试图从中读取。当您使用O_RDWR 打开队列时,请参阅mq_open,它应该可以工作。

      调试提示使用mq_timedreceive,以便您检查错误。

      【讨论】:

        猜你喜欢
        • 2020-04-25
        • 2019-03-17
        • 2020-11-27
        • 1970-01-01
        • 2020-04-18
        • 2021-12-07
        • 1970-01-01
        • 2016-03-21
        • 2015-04-12
        相关资源
        最近更新 更多