当使用python脚本作为CGI时,子进程Popen无法运行后台进程

时间:2019-05-22 16:14:56

标签: python apache cgi

我正在尝试从CGI python脚本在后台运行另一个Python脚本,并希望该脚本在后台运行进程而不等待其他脚本完成。不知何故,当我从Linux shell运行相同的代码时,我可以在后台运行其他python脚本。但是,当我尝试通过CGI进行同样的操作时,前端会继续加载,直到其他脚本完成为止,而不仅仅是使其在后台运行。

我尝试在Linux Shell上运行相同的程序,并且它可以工作。当我转向CGI时,脚本将等待其他过程完成。

python1.py:

command = [sys.executable,'python2.py', str(senddata)]
proc=subprocess.Popen(command,shell=False,stdin=None,stdout=None,stderr=None,close_fds=True)

print("Content-type: text/html\r\n\r\n")

print("The script is running in background! Expect an email in 10 minutes.")

python2.py: 该脚本需要2-5分钟的时间来执行,然后向群组发送电子邮件。

预期输出将显示以下消息:

  

该脚本在后台运行!希望在10分钟内收到一封电子邮件。

然后在后台运行python2.py,而无需等待它完成。

1 个答案:

答案 0 :(得分:0)

Web服务器将保持客户端响应处于活动状态(使客户端保持在“加载”状态),直到CGI程序的所有输出已被收集并转发给客户端为止。 Web服务器知道已经收集了所有输出的方式是看到CGI进程的标准输出流已关闭。这通常在CGI进程退出时发生。

出现此问题的原因是,当告诉subprocess.Popenstdout=None执行程序时,产生的程序将共享其父级的标准输出流。这意味着您的后台程序共享CGI进程的标准输出。这意味着从网络服务器的角度来看,流保持打开状态,直到两个进程都退出。

要解决此问题,请使用stdout=subprocess.PIPE启动后台进程。如果CGI进程终止时后台进程的stdout被关闭,则异常,请尝试使用stdout=open('/dev/null')启动它。

后台进程的stdinstderr将遇到相同的问题;它们将与CGI流程共享。只要后台进程不尝试从其标准输入中读取内容,AFAIK共享这些文件都不会造成麻烦,但是,如果这样做(或者如果您只是想保持谨慎),则可以像对待{ {1}}并将其设置为stdout或将它们与subprocess.PIPE关联。

更多细节位于https://docs.python.org/2/library/subprocess.html#popen-constructor