如果在消息队列打开之前调用 c mq_open() 则不会连接

Posted

技术标签:

【中文标题】如果在消息队列打开之前调用 c mq_open() 则不会连接【英文标题】:c mq_open() doesn't connect if it's called before message queue is open 【发布时间】:2020-04-04 05:23:18 【问题描述】:

所以我有两个进程。它们各自创建自己的消息队列,并尝试相互连接。但是,由于某种原因,这只适用于一种方式。

进程一具有以下内容:

struct mq_attr attr;
  int flags = O_RDWR | O_CREAT;
  attr.mq_flags = 0;
  attr.mq_maxmsg = 3; // ***
  attr.mq_msgsize = sizeof(cache_request);
  attr.mq_curmsgs = 0;

  mqd_t fd, fd2;
  mq_unlink("/mq_one");
  fd2 = mq_open("/mq_two", flags,(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),&attr );
  while((fd = mq_open("/mq_one", O_RDWR)) == -1)
    printf("Couldnt connect to message queue in cache\n");
    sleep(2);
  
  mq_close(fd2);
  mq_unlink("/mq_two");


  printf("connected to message queue.\n");

流程二有以下内容:

mqd_t fd, fd2;
    //mq_unlink("/mq_one");
    struct mq_attr attr;
    int flags = O_RDWR | O_CREAT;
    attr.mq_flags = 0;
    attr.mq_maxmsg = 3; // ***
    attr.mq_msgsize = sizeof(cache_request);
    attr.mq_curmsgs = 0;

    fd = mq_open("/mq_one", flags,(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),&attr );
    printf("opened message queue /mq_one.\n");
    if (fd < 0) 
            printf ("   Error %d (%s) on server mq_open.\n",errno, strerror (errno));
            mq_close(fd);
            mq_unlink("/mq_one");
        exit (1);
    
        while((fd2 = mq_open("/mq_two", O_RDWR)) == -1)
        printf("waiting on webproxy...\n");
        sleep(2);
      
        mq_close(fd2);
        mq_unlink("/mq_two");

本质上,每个进程都会打开(创建)自己的消息队列,然后在循环中等待另一个进程尝试连接。问题在于,这只适用于在进程二之前启动进程一,反之亦然。如果我先启动进程 2,那么当我启动进程 1 时,进程 2 退出循环并继续运行,但进程 1 仍处于循环中,即使它应该看到第一个消息队列。我不明白为什么会这样。

【问题讨论】:

***.com/q/61021812/905902 【参考方案1】:

你必须处理两个问题: * 在进程 P1 中删除 mq_one 的时间 * 处理持久化(左连接)

当您在 P1 之前启动 P2 时,P2 将创建 /mq_ope,但 P1 将删除它。此时 P1 将(永远)等待 /mq_one,但 P2 不会再次尝试创建 p1。

考虑不同的策略: * 每个程序(P1,P2)只会在退出时删除它创建的队列。

这应该允许程序正常工作,无论时间如何(谁先开始),也无论状态如何(前一次运行是否有剩余)。

【讨论】:

以上是关于如果在消息队列打开之前调用 c mq_open() 则不会连接的主要内容,如果未能解决你的问题,请参考以下文章

消息队列 ENOMEM

消息队列 mq 发送错误。错误的文件描述符

尝试使用 POSIX 消息队列创建消息队列时权限被拒绝

MassTransit 确保在发布消息之前创建队列

POSIX 队列配置

POSIX的IPC方式:消息队列共享内存