【问题标题】:Error implementing posix message queue - "Function not implemented"实现 posix 消息队列时出错 - “功能未实现”
【发布时间】:2012-02-11 08:36:29
【问题描述】:

我编写了这段代码来创建一个 posix 消息队列。但我收到“功能未实现”错误。

第一季度。是平台相关的问题吗? [正在使用 Ubuntu 10.10] 我在某处读到需要重建内核以启用消息队列!?

第二季度。我还阅读了一些关于在实际使用消息队列之前启动 mqueue 服务器的内容?

谁能解释一下..

#include <mqueue.h>     /* message queue stuff */
#include <iostream>
#include <unistd.h>     /* for getopt() */
#include <errno.h>      /* errno and perror */
#include <fcntl.h>      /* O_flags */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main(int argc, char **argv)
{

mqd_t msgQueueDescriptor;
mq_attr attr;

char Msg[]="msg";

attr.mq_maxmsg = 10;
attr.mq_msgsize = sizeof(Msg);
attr.mq_flags = 0;

msgQueueDescriptor = mq_open("/myQueue", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH , attr );
cout << msgQueueDescriptor << " " << errno << " " << strerror(errno);
mq_close(msgQueueDescriptor);

return 0;
}

【问题讨论】:

  • 根据mq_overview(7),POSIX 消息队列在构建内核时默认启用,但 Ubuntu 打包程序可能已将其关闭。
  • @larsmans 我该如何确认?这会成为 Ubuntu 发行说明的一部分吗?如果它真的关闭了,我该如何重新打开它?
  • 如果 ubuntu 真的把它们关掉的话,我会觉得很奇怪。在 fedora 15 上,您的示例编译和链接成功。
  • 您可能想通过 Synaptic 下载内核源代码包并检查其配置;你得到的错误肯定是ENOSYS,这意味着没有系统调用。我认为打开 MQ 将涉及重新编译内核。不过,如果默认内核不支持 MQ,我会感到非常惊讶。
  • 这在 Ubuntu 10.04.3 上编译、链接和运行。验证您的内核是否配置了所需的标志。看看/boot/config*

标签: c++ linux posix message-queue ubuntu-10.10


【解决方案1】:

我想我已经意识到问题出在哪里,或者更确切地说是一个错误。

这是我从here读到的-

[参考 mq_open()]

返回:如果队列成功,则返回一个有效的消息队列描述符 已创建,或 -1(设置了 errno)。

所以,我应该在实际发生错误时检查 errno 的值!。但是在上面的代码中,我只是打印值,而不管是否发生错误,因此它打印的是与存储在 errno 中的一些 garbage 值相对应的错误消息。

所以我的代码应该是这样的 -

if ((msgQueueDescriptor = mq_open("/myQueue", O_RDWR|O_CREAT, 0664 ,NULL ) == -1))
{
    cout << msgQueueDescriptor << " " << errno << " " << strerror(errno);
}
else
{
   cout << "All is well" ;
} 

我是不是把自己弄傻了:p

PS:就 Ubuntu 10.10 上启用的消息队列而言,我检查了“n.m.”提到的标志,它们非常启用,我现在可以使用消息队列了。谢谢你们所有人 - larsmans、VJovic、n.m.、Joachim Pileborg、jørgensen。

关于我的第二个问题

第二季度。我之前也读过一些关于启动 mqueue 服务器的内容 实际使用消息队列?

我认为这是 QNX 特有的要求。

【讨论】:

  • 重要的是要记住,没有库函数将errno 设置为零(至少,在标准 C 库中没有),并且您应该只检查 errno,如果最后一个函数可能设置它实际上表明它失败了。反例:在 Solaris 上,许多 stdio 调用检查输出是否为 tty,如果不是,则离开 errno == ENOTTY,即使调用完全成功。所以,是的,你自欺欺人了,但你从中吸取了教训,所以这是一次宝贵的经验。
  • 至于 Q2:如果手册页中没有关于启动 mqueue server 的内容(而且我从未见过任何提及它的内容),那么就没有必要这样做 - 无论 QNX 怎么想关于情况。
  • 检查errno 仅应在函数失败时进行(除非另有说明)。实际上,阅读errnohere 上的官方 POSIX 规范,它说 本卷 IEEE Std 1003.1-2001 中的任何函数都应将 errno 设置为 0。成功调用函数后的 errno 设置未指定除非该函数的描述指定不得修改 errno。
  • 判决:不是傻瓜。有帮助的学习者,是的:) 干杯
猜你喜欢
  • 2014-01-18
  • 1970-01-01
  • 2014-01-25
  • 2012-10-11
  • 2020-12-01
  • 2019-06-09
  • 1970-01-01
  • 2020-03-05
  • 2011-11-04
相关资源
最近更新 更多