python - 从 CGI 脚本启动后台进程/守护进程

标签 python apache cgi fork

我正在尝试从 CGI 脚本启动后台进程。基本上,当提交表单时,CGI 脚本将向用户指示他或她的请求正在被处理,而后台脚本执行实际处理(因为处理往往需要很长时间。)我面临的问题是 Apache 在子脚本终止之前不会将父 CGI 脚本的输出发送到浏览器。

一位同事告诉我,我想做的事情是不可能的,因为没有办法阻止 Apache 等待 CGI 脚本的整个进程树死亡。然而,我也在网上看到了许多关于“双叉”技巧的引用,它应该可以完成这项工作。该技巧在 this Stack Overflow answer 中有简洁的描述。 ,但我在其他地方看到过类似的代码。

这是我编写的一个简短脚本,用于测试 Python 中的双叉技巧:

import os
import sys

if os.fork():
    print 'Content-type: text/html\n\n Done'
    sys.exit(0)

if os.fork():
    os.setsid()
    sys.exit(0)

# Second child
os.chdir("/")
sys.stdout.close()
sys.stderr.close()
sys.stdin.close()

f = open('/tmp/lol.txt', 'w')

while 1:
     f.write('test\n')

如果我从 shell 运行它,它完全符合我的预期:原始脚本和第一个后代死亡,第二个后代继续运行,直到它被手动杀死。但是如果我通过 CGI 访问它,页面将不会加载,直到我杀死第二个后代或 Apache 因为 CGI 超时而杀死它。我也试过用 os._exit(0) 替换第二个 sys.exit(0),但没有区别。

我做错了什么?

最佳答案

不要 fork - 单独运行批处理

这种双重 fork 方法是某种 hack,对我来说这表明它不应该这样做:)。无论如何,对于 CGI。根据一般原则,如果某事太难完成,您可能以错误的方式接近它。

幸运的是,您提供了有关您需要的背景信息 - 一个 CGI 调用来启动一些独立发生的处理并返回给调用者。可以肯定 - 有一些 unix 命令可以做到这一点 - 安排命令在特定时间 (at) 或 CPU 空闲时 (batch) 运行。所以改为这样做:

import os

os.system("batch <<< '/home/some_user/do_the_due.py'")
# or if you don't want to wait for system idle, 
#   os.system("at now <<< '/home/some_user/do_the_due.py'")

print 'Content-type: text/html\n'
print 'Done!'

你有它。请记住,如果有一些输出到 stdout/stderr,它们将被邮寄给用户(这有利于调试,但否则脚本可能应该保持安静)。

PS。我只记得 Windows 也有 at 的版本,因此只需对调用稍作修改,您也可以在 windows 上的 apache 下工作(与不会的 fork 技巧相比)在 Windows 上工作)。

PPS。确保运行 CGI 的进程未在 /etc/at.deny 中排除在调度批处理作业中

关于python - 从 CGI 脚本启动后台进程/守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6024472/

相关文章:

python - Axes3D.text() 注释 3D 散点图

php - 为什么要避免使用 LAMP 托管的 Python 的 CGI?

python - cgi 文件 .py 未执行;显示文件

python - pyautogui 自动下移/上移和 ctrl-c 不起作用

python - 如何在Python中访问文件(.txt)中的下一行

python - 如何在 Pandas 中制作非数值数据的条形图

python - python cgi 的 crontab 权限

python - 使用虚拟环境配置 mod_wsgi 时出现问题

apache - 在Docker中运行Apache和Cron

java - 终止 Windows 服务时未调用 Stop 方法