c - FreeBSD 不会在 fork 上保留 POSIX 消息队列描述

标签 c linux message-queue freebsd

我有一个测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <mqueue.h>
#include <errno.h>
#include <fcntl.h>

int main() {
  struct mq_attr attrs;
  attrs.mq_maxmsg = 10;
  attrs.mq_msgsize = sizeof(int);

  const char name[] = "/test-queue";

  mqd_t q = mq_open(name, O_CREAT | O_RDWR, 0600, &attrs);
  if (q == (mqd_t)-1) {
    perror("mq_open");
    exit(EXIT_FAILURE);
  }

  mq_unlink(name); // it doesn't matter if I do this at the end or not

  if (fork()) {
    int msg = 666;
    if (mq_send(q, (const char *)&msg, sizeof(msg), 1)) {
      perror("mq_send");
      exit(EXIT_FAILURE);
    }
  } else {
    int msg;
    unsigned priority;
    if (mq_receive(q, (char *)&msg, sizeof(msg), &priority) == -1) {
      perror("mq_receive");
      exit(EXIT_FAILURE);
    }
    printf("%d\n", msg);
  }

  mq_close(q);

  return 0;
}

我在两个平台上使用 gcc -std=c99 -Wall -o mqtest mqtest.c -lrt 编译这个程序:

  • Linux kallikanzarid-desktop 3.8.0-31-generic#46-Ubuntu SMP Tue Sep 10 20:03:44 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
  • FreeBSD bsd.localhost 9.2-RELEASE FreeBSD 9.2-RELEASE #0 r255898: Thu Sep 26 22:50:31 UTC 2013 root@bake.isc.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64

在 Linux 上,一切正常。在 FreeBSD 上,我得到 mq_receive: Bad file descriptor。将 mq_unlink 调用移动到 main() 的末尾没有帮助。有没有办法解决这个问题,还是我必须推迟将队列标记为删除并在 fork 后重新打开它?

最佳答案

FreeBSD 确实保留了消息队列描述符。参见 mq_open(2):

FreeBSD implements message queue based on file descriptor. The descriptor is inherited by child after fork(2). The descriptor is closed in a new image after exec(3). The select(2) and kevent(2) system calls are supported for message queue descriptor.

编辑:

mqd_t 指向的结构确实 包含描述符。但是,如果您在 fork() 之后使用 fcntl() 测试该文件描述符,它也会返回 EBADF。

这是 FreeBSD 中的一个错误。但是这个错误是在文档中还是在实现中我不能说。

关于c - FreeBSD 不会在 fork 上保留 POSIX 消息队列描述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19500194/

相关文章:

c - pthread 库手册和我的 Linux 手册的第 2 节或第 7 节是否适用于 POSIX API?

linux - 如何在 Linux 上的 Netbeans 中使用外部 Tomcat 服务器?

c - Linux 上的 System V 消息队列无法按预期工作

java - ESB/消息队列快速入门

c - Valgrind:条件跳转或移动取决于未初始化的值

c - 我的 C 代码中的逻辑错误

c - 我在 c 中以这种方式使用 argc/argv 有什么问题?

linux - 如何在 Linux 运行时忽略 undefined symbol ?

.net - WM_DESTROY、WM_CLOSE绕过IMessageFilter

c - 位字节顺序如何影响 C 中的位移位和文件 IO?