有没有办法自动关闭fork()上的某些句柄?

时间:2011-03-31 22:23:27

标签: posix fork pipe handle

背景:我有一个大型的现有流程(它恰好在AIX上,基本上是POSIX语义),它是更大系统的一部分。现有流程旨在持续运行。此过程的新要求是处理一种新的复杂输入流。为了降低风险,我决定派生/执行子进程来进行实际的输入处理,这会将现有的主进程与崩溃或挂起格式错误的输入数据等问题隔离开来。

子进程从stdin读取数据并在处理后写入stdout。我已经设置了所有的通信管道,所以我可以将输入数据从主进程传递给子进程,并以另一种方式读取输出,这一切都正常(非阻塞以避免死锁等)。只要主进程从外部源接收(有限)输入流,子进程就会存在。

我的问题是管道手柄本身。主进程通过调用附加到子项stdin的管道上的close()来通知子项输入流已完成。只要主进程持有该管道写入端的句柄,这就可以工作。如果由于其他一些无关的原因,主要流程决定分叉怎么办?然后,这将为管道的写端创建两个句柄,这意味着当我尝试关闭stdin管道的写端时,子进程将不会注意到,因为还有另一个句柄写入结束了。那个其他打开的手柄是我无法控制的。

我知道我可以在文件描述符上设置FD_CLOEXEC位,以便在exec()完成时自动关闭。但是,这不能防止主要过程分叉但不执行的情况。

这个问题的一般解决方案是什么?我只想到几个想法:

  1. 确保(通过检查)现有流程不会在不执行exec的情况下任意分叉。这可能是可能的,但不是一般解决方案。
  2. 在启动时,fork一个长期存在的帮助程序进程,其唯一的责任是定期派生/执行执行实际处理的子进程。这样,帮助者的句柄上下文是已知的并且可以很好地控制。但是,这很烦人,因为帮助程序需要某种方式来知道输入流已经结束而不是关闭标准输入。

1 个答案:

答案 0 :(得分:2)

很少没有exec的标准系统库fork。这很不寻常。 Unix或Linux中没有close-on-fork工具,我怀疑它在AIX上。如果您真的非常关心那么AIX上有可加载的内核扩展。据推测,你知道关于执行官的fcntl。如果你的同事正在写无执行力的分叉,那么我就无法提供太多帮助。