python twisted:用于后台非返回处理的fork

python twisted:用于后台非返回处理的fork,python,fork,twisted,Python,Fork,Twisted,如何在twisted中正确地分叉子进程,该子进程不使用twisted中的任何内容(但使用父进程中的数据)(例如,处理父进程中某些数据的“快照”并将其写入文件,而不阻塞) 似乎如果我在os.fork()之后在子进程中执行类似clean shutdown的操作,就会关闭父进程中的一些套接字/描述符;我所看到的避免这种情况的唯一方法是执行os.kill(os.getpid(),signal.SIGKILL),这看起来确实是个坏主意(尽管没有直接的问题) (此外,如果dict在父进程中更改,是否也会在子

如何在twisted中正确地分叉子进程,该子进程不使用twisted中的任何内容(但使用父进程中的数据)(例如,处理父进程中某些数据的“快照”并将其写入文件,而不阻塞)

似乎如果我在
os.fork()
之后在子进程中执行类似clean shutdown的操作,就会关闭父进程中的一些套接字/描述符;我所看到的避免这种情况的唯一方法是执行
os.kill(os.getpid(),signal.SIGKILL)
,这看起来确实是个坏主意(尽管没有直接的问题)

(此外,如果dict在父进程中更改,是否也会在子进程中更改?快速测试表明它不会更改,尽管.OS/内核是debian stable/sid)

(通常从twisted.internetimport reactor;reactor.spawnProcess以
的形式提供)可以在系统上生成运行任何可用可执行文件的进程。子流程不需要使用Twisted,甚至不需要使用Python

不要自己调用
os.fork
。正如您所发现的,它与流程状态有许多非常特殊的交互作用,
spawnProcess
将为您管理

os.fork
的问题包括:

  • 分叉复制当前进程状态,但不复制线程状态。这意味着在修改一些全局状态中间的任何线程都会留下半个破损的东西,可能持有一些永远不会被释放的锁。在应用程序中不运行任何线程?您是否审核了您使用的每个库及其每个依赖项,以确保它们中没有任何一个曾经或将永远使用后台线程进行任何操作
  • 您可能认为您只接触了应用程序内存的某些区域,但由于Python的引用计数,您甚至可以在外围设备上查看(或在堆栈上)的任何对象的引用计数都可能增加或减少。增加或减少refcount是一个写操作,这意味着整个页面(而不仅仅是一个对象)被复制回进程中。因此,Python中的分叉进程倾向于积累比分叉C程序更大的复制集
  • 众所周知,许多库无法正确处理
    fork()
    ,如果您试图在
    fork
    之后但在
    exec
    之前使用它们,它们只会使程序崩溃
  • 用于告诉文件描述符在
    exec
    上关闭,但没有这样的标志让它们在
    fork
    上关闭。因此,如果您不小心管理对文件的访问,任何文件(包括日志文件,以及您可能根本不知道的库打开的任何后台临时文件)都可能会被悄悄损坏或截断

(我有点怀疑有一个像do nothing shell这样的
os.exec*
可以解决这个问题)你能详细解释一下“使用来自父进程的数据”是什么意思吗?您想要处理的数据的细节可能会对这个问题的最佳答案产生很大的影响。正如我所指出的,我需要访问父进程中的数据(甚至是数据的快照。这似乎正是fork()提供的)。这意味着,从一个可执行文件派生一个进程在这里是没有用的。但是访问什么数据呢?事实证明,在任何Python程序中,
os.fork
几乎肯定是被设计破坏的。唯一的例外可能是,如果您立即调用
os.execve
(或类似函数之一),它会丢弃所有数据,就像
spawnProcess
一样。因此,如果您将问题从“我如何使用
os.fork
?”改为“我如何与另一个进程共享X形式的数据?”或者干脆改为“我如何在扭曲的使用程序中以X形式持久化数据?”我在使其持久化方面没有任何问题。我有兴趣尝试以更多的方式使其原子化。不,我一点也不觉得os.fork坏了。它在许多情况下(以及在整个
多处理过程中
)都能很好地工作,并且可以用于处理大型numpy阵列,例如,在多个内核上使用python代码,而无需在内存中复制它们。它可以很好地用于OP方式,但我正试图找出如何做得更好。@HoverHell,它实际上在许多令人惊讶的方面被打破了。如果您想做的是在进程之间共享一个大的NUMPY数组,请考虑使用<代码> NoMy.MimPux/Calp> @ GLYPH,关于它是如何被破坏的任何引用?