为什么os.execvp阻止apache但不阻止shell?

时间:2014-11-18 23:25:08

标签: python

我正在寻找一种方法,在普通的python(没有额外的库)中启动将在网页返回后运行的后台进程。

在shell中,下面的脚本退出,然后打印" Hello World"。但是,在浏览器中,它会阻塞,直到two.py完成。

#!/usr/bin/python
import os
import sys

def run():
    program = "python"
    pid = os.fork()
    if not pid:
        os.execvp(program, (program,"two.py"))

run()

print "Content-type: text/html"
print ""
print "Hello, World!"

1 个答案:

答案 0 :(得分:0)

我不是100%肯定,但我认为这是因为Apache不是在等待您的流程,而是在整个流程组中。

当您fork新流程时,它会继承您的流程组。而exec并没有改变这一点。如果要强制它分离,则必须明确地执行此操作,例如,使用setpgrp

pid = os.fork()
if not pid:
    os.setpgrp()
    os.execvp(program, (program,"two.py"))

根据您的平台,这也可能意味着它会获得一个新会话,这意味着它不再拥有控制终端,但我不认为您关心它。


但是,使用daemon库重写two.py可能是更好的设计。然后,无论你如何产生它,它都会照顾守护本身。运行它你的脚本或直接从Apache,或者shell,在后台,无论如何,它永远不会让任何人等待它,与终端,zombify等纠缠在一起。