3

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

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

(此外,如果 dict 在父进程中发生更改,它会不会在子进程中也发生更改?快速测试表明它不会更改。操作系统/内核是 debian stable / sid)

4

1 回答 1

0

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

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

其中的问题os.fork是:

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