有没有一种方法可以自动关闭fork()上的某些句柄? [英] Is there a way to automatically close certain handles on a fork()?

查看:238
本文介绍了有没有一种方法可以自动关闭fork()上的某些句柄?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Background: I've got a large existing process (it happens to be on AIX, so basically POSIX semantics) that's part of an even larger system. The existing processes are designed to run continuously. A new requirement for this process is to handle a new kind of complex input stream. In order to reduce risk, I've decided to fork/exec a child process to do the actual input processing, which isolates the existing main process from problems such as crashes or hangs on malformed input data.

子进程从stdin读取数据,并在处理后写入stdout.我已经设置了所有通信管道,因此可以将输入数据从主进程传递给子进程,并以另一种方式读取输出,这一切都很好(非阻塞以避免死锁,等等).子进程的生存时间与主进程从外部源接收(有限)输入流所花费的时间一样.

The child process reads data from stdin and writes to stdout after processing. I've got all the communication pipes set up so I can pass input data from the main process to the child, and read the output the other way, this all works fine (nonblocking to avoid deadlocks, etc). The child process lives as long as it takes for the main process to receive the (finite) input stream from an external source.

我有一个关于管道自身的问题.主进程通过在连接到孩子的stdin的管道上调用close()来通知孩子输入流已完成.只要主进程保持该管道的写入端的 only 句柄,此方法就起作用.如果主流程出于其他一些不相关的原因而决定分叉怎么办?然后,这将在管道的写入端创建两个句柄,这意味着当我尝试关闭stdin管道的写入端时,子进程将不会注意到,因为还有另一个要写入的句柄结束开放.另一个打开的手柄是我无法控制的.

The question I have is about the pipe handles themselves. The main process informs the child that the input stream has completed by calling close() on the pipe attached to the child's stdin. This works as long as the only handle to the write end of that pipe is held by the main process. What if the main process, for some other unrelated reason, decides to fork? This would then create two handles to the write end of the pipe, meaning when I try to close the write end of the stdin pipe, the child won't notice because there is still another handle to the write end open. That other open handle is out of my control.

我知道可以在文件描述符上设置FD_CLOEXEC位,以便在完成exec()后自动将其关闭.但是,这不能防止主进程派生但不执行的情况.

I know there is the FD_CLOEXEC bit that I can set on a file descriptor so that it is automatically closed when an exec() is done. However, this won't protect against the case where the main process forks but does not exec.

此问题的一般解决方案是什么?我只能想到几个主意:

What's the general solution to this problem? I can think of only a couple of ideas:

  1. 确保(通过检查)在不执行执行的情况下,现有过程不会任意分叉.这可能是可行的,但不是通用解决方案.
  2. 在启动时,派生一个长期存在的帮助程序进程,其唯一职责是定期派生/执行执行实际处理的孩子.这样,帮助者的句柄上下文是已知的,并且可以得到很好的控制.但是,这很烦人,因为除了关闭 stdin之外,帮助程序还需要某种方法来知道输入流已结束.
  1. Ensure (through inspection) that the existing process doesn't fork arbitrarily without also doing an exec. This may be possible but is not a general solution.
  2. At startup, fork a long-lived helper process whose sole responsibility is to periodically fork/exec the child that does the actual processing. That way the helper's handle context is known and can be well-controlled. However, this is annoying because the helper needs some way to know that the input stream has ended other than closing its stdin.

推荐答案

很少没有exec的标准系统库fork.这很不寻常.在Unix或Linux中没有可分叉的工具,而我在AIX上对此表示怀疑.如果您真的很在意AIX上有可加载的内核扩展.大概您知道fcntl可以在exec上关闭.如果您的同事正在编写无执行程序的分叉,那么我不会提供太多帮助.

Very few No standard system libraries fork without exec. It's quite unusual. There is no close-on-fork facility in Unix or Linux, and I doubt it on AIX. There are loadable kernel extensions on AIX if you really care that much. Presumably you know about fcntl for close on exec. If your co-workers are writing exec-less forks, then I can't offer much assistance.

这篇关于有没有一种方法可以自动关闭fork()上的某些句柄?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆