繁体   English   中英

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;
}

预期与实际结果

我希望这段代码可以简单地运行,打印派生进程的pid,然后退出。 相反,我得到以下错误(例如一个示例运行):

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);
}

还要按照手册页,确保最大消息数和msg大小的值有意义,否则您将获得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.)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM