由于您的工作调用与非工作调用之间的区别仅是“ -n”选项,因此问题很可能是由守护进程引起的(“ -n”阻止了此事件的发生)。
在POSIX上,守护进程涉及的步骤之一是派生并具有父出口。其中,其结果是使您的代码在与评估.tac文件不同的过程中运行。这也重新排列了.tac文件中启动的进程的子级/父级关系- 就像您的多进程进程池一样。
多处理池的进程从您启动的扭曲进程的父进程开始。但是,当该进程作为守护进程的一部分退出时,它们的父进程将成为系统初始化进程。这可能会导致一些问题,尽管可能不是您描述的问题。可能还有其他类似的低层实现细节,这些细节通常允许多处理模块工作,但会被守护进程破坏。
幸运的是,避免这种奇怪的相互作用应该很简单。Twisted的服务API允许您在守护程序完成后运行代码。如果使用这些API,则可以将多处理模块的进程池的初始化延迟到守护进程之后,并希望避免该问题。这是一个可能看起来像的例子:
from twisted.application.service import Service
class MultiprocessingService(Service):
def startService(self):
self.pool = multiprocessing.Pool(processes=processes)
MultiprocessingService().setServiceParent(application)
现在,分别地,您可能还会遇到与清理多处理模块的子进程有关的问题,或者可能是与通过Twisted的进程创建API Reactor.spawnProcess创建的进程有关的问题。这是因为正确处理子进程的一部分通常涉及处理SIGCHLD信号。但是,在这方面,扭曲和多处理不会合作,因此,其中一个将通知所有退出的孩子,而另一个将永远不会被通知。如果您根本不使用Twisted的API创建子进程,那么这对您来说可以- 但您可能要检查以确保多处理模块尝试安装的任何信号处理程序实际上“成功”并且没有得到替换为Twisted自己的处理程序。