使用全局单例实例在内存中存储子进程对象
我正在用 subprocess
来通过 Django 的网页界面启动一个长时间运行的进程。如果用户想要再次访问这个页面,我希望能给他们一个选项,让他们在之后可以终止这个 subprocess
。
我该怎么做呢?我在 Java 中实现过类似的功能,创建了一个全局的单例 ProcessManager 字典来把进程对象存储在内存中。我能在 Python 中做类似的事情吗?
编辑
没错,使用单例和一个 ProcessManager 的哈希表是个干净的做法。Emmanuel 的代码经过一些修改后运行得很好。
谢谢
2 个回答
1
你可以在Python中使用和Java一样的方法,也就是把进程的引用存储在一个模块变量里,或者实现一种单例模式。
不过和Java相比,Python有个问题,就是它没有像Servlet那样丰富的规范,也没有接口来处理应用程序的启动或结束。在大多数情况下,你不需要担心你的应用程序有多少个实例在运行,因为你从持久存储中获取所有数据。但在这种情况下,你需要了解你的应用程序是如何部署的。
如果你的应用程序只有一个长时间运行的实例(比如一个FastCGI实例,或者在cherrypy上运行的单个WSGI应用),你可以把处理功能隔离到一个单独的模块中,并在模块被导入时加载它(在一个应用程序中,任何模块只会被导入一次)。如果有多个实例(比如多个FastCGI实例,或者普通的CGI脚本),你最好把子进程分离出来,并把它们的ID存储在持久存储中(比如数据库或文件),然后根据需要和当前运行的进程列表进行交叉比对。
1
我觉得在Python中实现单例模式的一个简单方法是通过类属性:
import subprocess
class ProcessManager(object):
__PROCESS = None;
@staticmethod
def set_process(args):
# Sets singleton process
if __PROCESS is None:
p = subprocess.Popen(args)
ProcessManager.__PROCESS = p;
# else: exception handling
@staticmethod
def kill_process():
# Kills process
if __PROCESS is None:
# exception handling
else:
ProcessManager.__PROCESS.kill()
然后你可以通过这个类来使用:
from my_module import ProcessManager
my_args = ...
ProcessManager.set_process(my_args)
...
ProcessManager.kill_process()
注意事项:
ProcessManager
负责创建进程,这样它的结束方式也能保持一致- 我对多线程的知识不够,不确定这个方法在多线程模式下是否有效