【问题标题】:python-twisted: fork for background non-returning processingpython-twisted:用于后台不返回处理的 fork
【发布时间】:2012-11-01 16:37:12
【问题描述】:

如何正确派生一个不使用任何来自 twisted 的子进程(但使用来自父进程的数据)(例如,处理来自父进程的某些数据的“快照”并将其写入文件,无需阻塞)?

似乎如果我在os.fork() 之后在子进程中执行干净关闭之类的操作,它会关闭父进程中的一些套接字/描述符;避免这种情况的唯一方法是使用os.kill(os.getpid(), signal.SIGKILL),这似乎是个坏主意(尽管没有直接问题)。

(另外,如果一个dict在父进程中发生了变化,它会不会在子进程中也发生变化?快速测试表明它不会改变,但操作系统/内核是debian stable / sid)

【问题讨论】:

  • (我有点怀疑os.exec* 中的一个类似无操作外壳的东西会解决这个问题)
  • 您能否详细说明“使用来自父进程的数据”的含义?您要使用的数据的具体细节可能会对这个问题的最佳答案产生重大影响。

标签: python fork twisted


【解决方案1】:

IReactorProcess.spawnProcess(通常以from twisted.internet import reactor; reactor.spawnProcess 提供)可以生成一个进程,该进程在您的系统上运行任何可用的可执行文件。子进程不需要使用 Twisted,甚至不需要使用 Python。

不要自己打电话给os.fork。正如您所发现的,它与进程状态有很多非常特殊的交互,spawnProcess 将为您管理。

os.fork 的问题包括:

  • 分叉复制您当前的进程状态,但不复制线程的状态。这意味着在修改某些全局状态中间的任何线程都会使事情半途而废,可能持有一些永远不会被释放的锁。不要在您的应用程序中运行任何线程?您是否审核了您使用的每个库及其每个依赖项,以确保它们中没有一个曾经或将曾经使用后台线程做任何事情?
  • 您可能认为您只触及应用程序内存的某些区域,但由于 Python 的引用计数,您甚至外围查看(或存在于堆栈中)的任何对象都可能会增加或减少引用计数。增加或减少引用计数是一种写操作,这意味着整个页面(不仅仅是一个对象)被复制回您的进程。因此,Python 中的分叉进程往往会积累比分叉的 C 程序更大的复制集。
  • 许多库,例如著名的 all of the libraries that make up the systems on macOS and iOS,无法正确处理 fork(),如果您尝试在 fork 之后但在 exec 之前使用它们,只会使您的程序崩溃。
  • There's a flag 告诉文件描述符在 exec 上关闭 - 但没有这样的标志让它们在 fork 上关闭。因此,如果您不仔细管理对它们的访问权限,任何文件(包括日志文件,以及由库打开的任何后台临时文件,您甚至可能都不知道)都可能被静默损坏或截断。

【讨论】:

  • 正如我所指出的,我需要访问父进程中的数据(甚至访问数据的快照。这似乎正是 fork() 提供的)。这意味着,从可执行文件生成进程在这里没有用。
  • 但是访问什么数据?事实证明,任何 Python 程序中的os.fork 几乎肯定会被破坏(按设计)。唯一的例外可能是您立即调用 os.execve(或类似函数之一) - 这会丢弃您的所有数据,就像 spawnProcess 所做的那样。因此,如果您将问题从“我如何使用os.fork?”更改为会有所帮助。到“如何以 X 的形式与另一个进程共享数据?”或者甚至可以一直走到“如何在使用 Twisted 的程序中以 X 的形式保存数据?”
  • 我没有任何问题让它一般持续存在。我有兴趣尝试以更多方式使其更像原子。不,在我看来,os.fork 完全没有损坏。它在许多情况下工作得很好(也适用于multiprocessing),并且可用于处理,例如,在多个内核上使用 python 代码的大型 numpy 数组,而无需在内存中复制它们。并且它可以很好地用于 OP 方式,但我正在尝试弄清楚如何做到这一点更好。
  • @HoverHell,它实际上以许多令人惊讶的方式被破坏。如果您想要在进程之间共享一个大型 numpy 数组,请考虑使用 numpy.memmap docs.scipy.org/doc/numpy/reference/generated/…
  • @Glyph,有没有关于它是如何被破坏的参考资料?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 2014-08-28
相关资源
最近更新 更多