Posix 条消息地址错误 mq_open
Posix messages Bad adress at mq_open
问题总结
我正在编写一个程序,旨在分叉多个进程,每个进程打开一个唯一的消息队列来接收消息。但是,每次我 运行 我的程序时,每个分叉进程在使用 mq_open
.
初始化各自的队列时都会遇到 Bad address
错误
一些细节
我的代码旨在按照 "/_*
的形式动态生成消息队列名称,其中 *
是一些唯一的字母(a、b、c 等)但是,在尝试使用字符串 "/hello"
替换动态生成的名称的相同代码,程序仍然失败并出现相同的错误。
这让我相信问题是创建新队列失败,而不是名称本身的问题。但是,我相信我传递 O_CREAT 是正确的,所以我不知道问题出在哪里。
我确实在这个问题上找到了 ,但那个人似乎没有遇到同样的问题。我相信我已经在下面包含了所有相关代码,但如果需要更多,请告诉我。非常感谢任何帮助!
我的代码
这里是实际调用mq_open
的封装函数:
mqd_t init_queue(char *desc, long m_flags, long m_max, long m_size)
{
mqd_t mq_des;
struct mq_attr attr;
mode_t mode = 0664;
attr.mq_maxmsg = m_max;
attr.mq_msgsize = m_size;
attr.mq_flags = m_flags;
if ((mq_des = mq_open(desc, O_CREAT | O_RDWR, mode, attr)) == -1) {
perror("Error at init_queue");
exit(1);
}
return mq_des;
}
这里是调用init_queue
的函数。我也在顶部粘贴了相关的宏和辅助函数 (nid
),因此您可以看到这些:
#define DESCPREF "/_"
#define DESCSIZE 4
#define FIRSTID 97
#define MAXMSGS 200
#define M_SIZE sizeof(struct _message)
char *nid(int id)
{
char *desc = malloc(sizeof(char) * DESCSIZE);
char c = id;
snprintf(desc, DESCSIZE, "%s%c", DESCPREF, c);
return desc;
}
int node(int id, int inc)
{
/* INIT */
proc_info me = malloc(PROCINF_SIZE);
me->id = id;
me->curr = id - FIRSTID + 1;
me->inc = inc;
char *mypath = nid(id);
me->listen = init_queue(mypath, O_NONBLOCK, MAXMSGS, M_SIZE);
/* Do some stuff ... */
close_queue(me->listen);
mq_unlink(mypath);
free(me);
return 0;
}
最后,分叉我的各个进程的代码:
int main(){
pid_t pid;
int nodes = TESTNODES;
for (int i = 0; i < nodes; i++) {
if ((pid = fork()) == -1) {
perror("Fork error\n");
exit(1);
} else if (pid == 0) {
node(FIRSTID + i, nodes);
exit(0);
} else {
printf("Forked: %d\n", (int) pid);
}
}
return 1;
}
预期与实际结果
我希望这段代码只是 运行,打印分叉进程的 pids,然后退出。相反,我收到以下错误(例如 运行):
Forked: 27448
Forked: 27449
Error at init_queue: Bad address
Error at init_queue: Bad address
Forked: 27450
Error at init_queue: Bad address
Forked: 27451
Error at init_queue: Bad address
Forked: 27452
Error at init_queue: Bad address
如前所述,我还尝试使用纯字符串 "/hello"
作为 mq_open
的输入名称并收到相同的错误集(在这种情况下所有五个错误也都失败了) .
您需要将指针传递给 mq_attr 结构,例如:
if ((mq_des = mq_open(desc, O_CREAT | O_RDWR, mode, &attr)) == -1) {
perror("Error at init_queue");
exit(1);
}
还要根据手册页确保最大消息和消息大小的值有意义,否则您将得到一个 EINVAL。
EINVAL O_CREAT was specified in oflag, and attr was not NULL, but
attr->mq_maxmsg or attr->mq_msqsize was invalid. Both of
these fields must be greater than zero. In a process that is
unprivileged (does not have the CAP_SYS_RESOURCE capability),
attr->mq_maxmsg must be less than or equal to the msg_max
limit, and attr->mq_msgsize must be less than or equal to the
msgsize_max limit. In addition, even in a privileged process,
attr->mq_maxmsg cannot exceed the HARD_MAX limit. (See
mq_overview(7) for details of these limits.)
问题总结
我正在编写一个程序,旨在分叉多个进程,每个进程打开一个唯一的消息队列来接收消息。但是,每次我 运行 我的程序时,每个分叉进程在使用 mq_open
.
Bad address
错误
一些细节
我的代码旨在按照 "/_*
的形式动态生成消息队列名称,其中 *
是一些唯一的字母(a、b、c 等)但是,在尝试使用字符串 "/hello"
替换动态生成的名称的相同代码,程序仍然失败并出现相同的错误。
这让我相信问题是创建新队列失败,而不是名称本身的问题。但是,我相信我传递 O_CREAT 是正确的,所以我不知道问题出在哪里。
我确实在这个问题上找到了
我的代码
这里是实际调用mq_open
的封装函数:
mqd_t init_queue(char *desc, long m_flags, long m_max, long m_size)
{
mqd_t mq_des;
struct mq_attr attr;
mode_t mode = 0664;
attr.mq_maxmsg = m_max;
attr.mq_msgsize = m_size;
attr.mq_flags = m_flags;
if ((mq_des = mq_open(desc, O_CREAT | O_RDWR, mode, attr)) == -1) {
perror("Error at init_queue");
exit(1);
}
return mq_des;
}
这里是调用init_queue
的函数。我也在顶部粘贴了相关的宏和辅助函数 (nid
),因此您可以看到这些:
#define DESCPREF "/_"
#define DESCSIZE 4
#define FIRSTID 97
#define MAXMSGS 200
#define M_SIZE sizeof(struct _message)
char *nid(int id)
{
char *desc = malloc(sizeof(char) * DESCSIZE);
char c = id;
snprintf(desc, DESCSIZE, "%s%c", DESCPREF, c);
return desc;
}
int node(int id, int inc)
{
/* INIT */
proc_info me = malloc(PROCINF_SIZE);
me->id = id;
me->curr = id - FIRSTID + 1;
me->inc = inc;
char *mypath = nid(id);
me->listen = init_queue(mypath, O_NONBLOCK, MAXMSGS, M_SIZE);
/* Do some stuff ... */
close_queue(me->listen);
mq_unlink(mypath);
free(me);
return 0;
}
最后,分叉我的各个进程的代码:
int main(){
pid_t pid;
int nodes = TESTNODES;
for (int i = 0; i < nodes; i++) {
if ((pid = fork()) == -1) {
perror("Fork error\n");
exit(1);
} else if (pid == 0) {
node(FIRSTID + i, nodes);
exit(0);
} else {
printf("Forked: %d\n", (int) pid);
}
}
return 1;
}
预期与实际结果
我希望这段代码只是 运行,打印分叉进程的 pids,然后退出。相反,我收到以下错误(例如 运行):
Forked: 27448
Forked: 27449
Error at init_queue: Bad address
Error at init_queue: Bad address
Forked: 27450
Error at init_queue: Bad address
Forked: 27451
Error at init_queue: Bad address
Forked: 27452
Error at init_queue: Bad address
如前所述,我还尝试使用纯字符串 "/hello"
作为 mq_open
的输入名称并收到相同的错误集(在这种情况下所有五个错误也都失败了) .
您需要将指针传递给 mq_attr 结构,例如:
if ((mq_des = mq_open(desc, O_CREAT | O_RDWR, mode, &attr)) == -1) {
perror("Error at init_queue");
exit(1);
}
还要根据手册页确保最大消息和消息大小的值有意义,否则您将得到一个 EINVAL。
EINVAL O_CREAT was specified in oflag, and attr was not NULL, but
attr->mq_maxmsg or attr->mq_msqsize was invalid. Both of
these fields must be greater than zero. In a process that is
unprivileged (does not have the CAP_SYS_RESOURCE capability),
attr->mq_maxmsg must be less than or equal to the msg_max
limit, and attr->mq_msgsize must be less than or equal to the
msgsize_max limit. In addition, even in a privileged process,
attr->mq_maxmsg cannot exceed the HARD_MAX limit. (See
mq_overview(7) for details of these limits.)