Я пытаюсь запустить фоновый процесс из сценариев CGI. В принципе, при отправке формы CGI script указывает пользователю, что его или ее запрос обрабатывается, в то время как фон script выполняет фактическую обработку (потому что обработка имеет тенденцию занимать много времени.) Проблема Я столкнулся с тем, что Apache не отправит вывод родительского CGI script в браузер до тех пор, пока не закончится дочерний script.
Мне сказал коллега, что то, что я хочу сделать, невозможно, потому что нет возможности предотвратить, чтобы Apache ожидал, что все дерево процессов CGI script умрет. Тем не менее, я также видел многочисленные ссылки в Интернете на трюк "двойной вилки", который должен выполнять эту работу. Трюк описывается лаконично в этом ответе на переполнение стека, но я видел аналогичный код в другом месте.
Вот короткий script, который я написал, чтобы проверить трюк двойного fork в 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')
Если я запустил это из оболочки, он делает именно то, что я ожидаю: исходный script и первый потомок умирают, а второй потомок продолжает работать, пока он не будет убит вручную. Но если я получаю доступ к нему через CGI, страница не будет загружаться, пока я не убью второго потомка, или Apache не убьет его из-за таймаута CGI. Я также попытался заменить второй sys.exit(0)
на os._exit(0)
, но нет никакой разницы.
Что я делаю неправильно?