我有一个相当大的数据库导入作业,我从 Web 界面(Flask)开始。在访问触发数据库导入的 URL 时,我在进行数据库插入之前分叉。
问题是,当我尝试停止 Web 服务(内置开发服务器上的 Ctrl+C)时,子进程反而停止,并且 Web 服务器继续在后台运行。不知何故,似乎 Web 服务器作业突然被推为后台守护进程,而子进程现在是主进程。
我想要实现的是一种“启动子进程然后忘记它”的方法,其中 Web 服务器只是启动子进程,然后再也不会打扰它,尤其是在涉及异常和类似情况时。
关于如何最好地解决这个问题的任何想法?
目前导入功能的测试代码为:
def import_start():
try:
pid = os.fork()
except OSError as e:
print "Exception in import_start"
sys.exit(1)
if pid == 0:
with open("/tmp/web_out.txt", "w") as f:
for x in range(100):
f.write("line %d\n" % (x))
f.flush()
sleep(10)
代码在烧瓶路由处理程序中启动:
import_start()
之后使用 Ctrl+C 将终止 import_start() 进程而不是 Web 服务器。我希望它是相反的,因为这两个进程在启动后应该完全独立。
更新:
我最终做了:
def start_import():
subprocess.Popen([sys.executable,__file__],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
def do_import():
with open("/tmp/web_out.txt", "w") as f:
for x in range(100):
f.write("line %d\n" % (x))
f.flush()
sleep(10)
if __name__ == "__main__":
do_import()
这有效(除了在我的网络服务器被杀死时杀死生成的进程),但我有点担心不以某种方式清理进程。我可能会研究 MQ 方法来解决这个问题,尽管这比仅仅产生一个新进程需要更多的复杂性。