【问题标题】:select() message queue failed as bad address(EFAULT) on AIX 6.1.0.0select() 消息队列在 AIX 6.1.0.0 上因错误地址 (EFAULT) 而失败
【发布时间】:2015-02-17 02:32:18
【问题描述】:

在 AIX 6.1.0.0 上,消息队列的 select() 系统调用支持,请参阅 http://www-01.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/select.htm?lang=en

但在调用 select() 后,下面的代码返回失败,出现 errno 14(EFAULT):

int msgid = msgget(MQ_KEY, IPC_CREAT|06666);
if (-1 == msgid) {
    if (errno != EEXIST) {
        ETRACE("msgget() failed: key[%d], errno[%d]", MQ_KEY, errno);
        return -1;
    }

    msgid = msgget(MQ_KEY, 0);
    if (-1 == msgid) {
        ETRACE("msgget() failed: key[%d], errno[%d]", MQ_KEY, errno);
        return -1;
    }
}
DTRACE("msgget() success: msgid[%d]", msgid);

/* time out */
struct timeval to;
to.tv_sec = 10;
to.tv_usec = 0;

/* select list */
struct {
    int msgids[1];
} rlist, wlist, elist;

rlist.msgids[0] = msgid;
wlist.msgids[0] = msgid;
elist.msgids[0] = msgid;

/* number of list */
int nlist = 1 << 16;

/* int ret = select(nlist, (struct fd_set*)&rlist, (struct fd_set*)&wlist, (struct fd_set*)&elist, &to); */
int ret = select(nlist, (struct fd_set*)&rlist, NULL, NULL, &to);
if (0 == ret) {
    WTRACE("select() timeout: ret[%d]", ret);
}
else if (ret < 0) {
    ETRACE("select() failed: ret[%d], errno[%d]", ret, errno);
}
else {
    ITRACE("select() success");
}

return 0;

【问题讨论】:

  • int nlist = 1 &lt;&lt; 16; 可能有点太大了。还有...rlist.msgids[0] = msgid; rlist 是什么?
  • 在 AIX 6.1.0.0 的手册中,关于 select() 中的第一个参数 Nfdsmsgs低 16 位给出了位掩码的长度,该位掩码指定哪个要检查的文件描述符;高 16 位给出了包含消息队列标识符的数组的大小。rlist 是存储的结构体 msgid。

标签: unix select ipc message-queue aix


【解决方案1】:

select()poll() 中的消息队列支持是 AIX 扩展,在 AIX 5.3 和更高版本上编译时默认不再启用。要启用它,请在第一个 #include 之前使用-D_MSGQSUPPORT(或#define _MSGQSUPPORT 1)进行编译。

select() 手册页上没有提到它,但poll() manual page 上提到了该选项,并且相同的标志启用了对这两种功能的消息队列支持。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-26
    • 2015-06-23
    • 1970-01-01
    • 2019-05-27
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多