如何等待命名管道的另一端打开?

mad*_*uri 3 c c++ unix posix named-pipes

我想在2个进程(AB)之间使用2个命名管道(a2bb2a)交换数据,如下所示:

  1. Process使用A创建a2bb2a管道mkfifo(3).
  2. 流程A启动流程B(使用fork(),exec*()甚至system())
  3. A等到B open()s a2bb2a
  4. A write()的数据 a2b
  5. B read()来自的数据 a2b
  6. B write()的数据 b2a
  7. A read()来自的数据 b2a

如何让进程A等待进程B open()s命名管道的另一端? - 即如何实施第3步?

编辑1:正如@EJP所提到的,可以使用读/写/选择来实现步骤3.但是,我想知道是否还有其他方法.

dco*_*cow 6

POSIX open的行为是为FIFO指定的.如果您使用的是Linux,请man 7 fifo进行一些讨论:

内核为至少一个进程打开的每个FIFO特殊文件保留一个管道对象.在传递数据之前,必须在两端打开FIFO(读取和写入).通常,打开FIFO块直到另一端打开.

进程可以在非阻塞模式下打开FIFO.在这种情况下,即使在写入端尚未打开任何人,只读打开也是成功的,并且只有在没有这样的设备或地址的情况下,只读打开失败,除非另一端已经打开.

所以你有两个选择:

  1. 使用阻止模式,open呼叫将阻塞,直到另一端打开,或
  2. 使用非阻塞模式并旋转open调用直到成功.

如果您的要求允许,您可以完全跳过命名管道(FIFO)并使用pipe.子进程将继续打开的文件描述符继承到管道的每一端,并且可以根据需要使用任何一个(不要忘记关闭不需要的描述符).


但是,考虑到你的最终目标是双向通信,我可能会建议一个(Unix域)socket和一些IO复用策略(select,poll,epoll,kqueue,等)?

  • 关键在于,两个进程必须通过以相同的顺序打开两个FIFO来进行协作-它们都必须在“ b2a”之前打开“ a2b”,反之亦然。如果一个打开了“ a2b”,而另一个打开了“ b2a”,则它们陷入僵局-第一个正在等待另一个打开“ a2b”,而第二个正在等待另一个打开“ b2a”,并且两者都挂起,直到另一个做预期的事情。 (2认同)