【发布时间】:2018-03-18 17:52:26
【问题描述】:
我在基于 flask 的 Web 应用程序中使用库 multiprocessing 来启动长时间运行的进程。执行此操作的函数如下:
def execute(self, process_id):
self.__process_id = process_id
process_dir = self.__dependencies["process_dir"]
self.fit_dependencies()
process = Process(target=self.function_wrapper, name=process_id, args=(self.__parameters, self.__config, process_dir,))
process.start()
当我想在这个 Web 应用程序上部署一些代码时,我重新启动了一个服务,该服务重新启动 gunicorn,由 nginx 提供服务。我的问题是,此重新启动会杀死此应用程序启动的所有子进程,就好像 SIGINT 信号已发送给所有子进程一样。我怎么能避免呢?
编辑: 阅读this post 后,看来这种行为是正常的。答案建议改用 subprocess 库。所以我重新提出我的问题:如果我想在 python 脚本中启动长时间运行的任务(它们是 python 函数)并确保它们能够在父进程中生存 OR 确保父进程进程(这是一个 gunicorn 实例)会在部署中存活下来吗?
最终编辑:我选择了@noxdafox 答案,因为它更完整。首先,使用进程排队系统可能是这里的最佳实践。然后作为一种解决方法,我仍然可以使用 multiprocessing 但在函数包装器中使用 python-daemon 上下文(请参阅here ans here)。最后,@Rippr 建议将 subprocess 与不同的进程组一起使用,这比使用 multiprocessing 分叉更干净,但涉及启动独立函数(在我的情况下,我从导入的库)。
【问题讨论】:
-
一目了然,我会尝试将此方法从烧瓶应用程序中分离出来,使其成为一个完全独立的进程。这样,子进程就不会随着烧瓶应用程序而死。例如,您可以将这项工作委托给 celery 应用程序。
-
谢谢。芹菜似乎是主要推荐的选择。但这涉及向我的项目添加更多依赖项,我想避免这种情况。真的没有办法从 python 脚本中启动一个完全独立的进程吗?
-
我还是不明白为什么会这样。孩子们应该成为 init 的孩子,直到他们终止他们的代码。
-
取决于您与该进程通信的需求,根据您使用的是 Python2 还是 Python3 以及您使用的平台,实现可能会有所不同。查看this question,它可能会为您提供一些答案。
-
我处理与文件的通信。我只是想了解为什么孩子们被关闭而不是成为孤儿..
标签: python nginx flask gunicorn python-multiprocessing