Как порождать процесс Python2.5 через Apache и сразу же вернуться под Windows - PullRequest
1 голос
/ 13 марта 2011

У меня есть два скрипта Python, один запускает другой с подпроцессом

invoke.py:

import subprocess
p = subprocess.Popen(['python', 'long.py'])
print "Content-Type: text/plain\n"
print "invoked (%d)" % (p.pid)

longtime.py:

import time
import os
print "start (%d)" %(os.getpid())
time.sleep(10)
print "end (%d)" %(os.getpid())

Когда я выполняюinvoke.py из оболочки возвращает сразу, а longtime.py работает в фоновом режиме (работает в Windows и Linux).Если я вызываю invoke.py через веб-интерфейс (Apache CGI), он работает под Linux , но не на машине с Windows , веб-сайт застревает и возвращается только после завершения longtime.py.

Как я могу настроить подпроцесс Python или Apache, чтобы получить то же поведение под Windows?В чем разница?

Возможно, конфигурация Apache в Windows чем-то отличается, но я что-то не нашел.

Linux: Debian, Python2.5.2, Apache2.2.9
Windows: WinXP, Python2.7, Apache2.2.17

Возможно, у вас есть и лучший подход к проектированию (потому что мне немного неловко, как я это делаю сейчас).

Зачем ?: У меня есть скрипт на веб-серверекоторый занимает довольно много времени для расчета (longtime.py).Я хочу активировать выполнение через веб-интерфейс.Веб-сайт должен немедленно вернуться, а longtime.py должен работать в фоновом режиме и записывать вывод в файл.Позже запрос из веб-интерфейса проверяет, создан ли файл, и считывает вывод.Я не могу использовать обычного облачного провайдера, так как он не поддерживает многопоточность.Также я не могу установить обработчик демона на веб-сервере, потому что процессы имеют максимальное время выполнения.

1 Ответ

0 голосов
/ 14 марта 2011

Я тестировал приведенный ниже код в Windows XP и OSX 10.6.6 (оболочка), и он завершается, не дожидаясь завершения дочернего процесса.

invoke.py:

from subprocess import Popen, PIPE
import platform


if platform.system() == 'Windows':
    close_fds=False
else: 
    close_fds=True

p = Popen('python long.py', stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, shell=True)
print "Content-Type: text/plain\n"
print "invoked (%d)" % (p.pid)

long.py

import time
import os
print "start (%d)" %(os.getpid())
time.sleep(10)
print "end (%d)" %(os.getpid())

Обновление: Проверено на Windows 7 + Apache 2.2.17 + Python 2.7 + mod_wsgi 3.3.

Файл mod_wsgi.so можно загрузить с здесь .Файл должен быть переименован в mod_wsgi.so и помещен в папку модулей Apache.

invoke.wsgi: из подпроцесса импорта Popen, платформа импорта PIPE

def application(environ, start_response):
    if platform.system() == 'Windows':
        close_fds=False
    else: 
        close_fds=True

    p = Popen('python "C:\testing\long.py"', stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, shell=True)

    status = '200 OK'
    output = "invoked (%d)" % (p.pid)    
    response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

*Файл 1026 * long.py был оставлен без изменений.

изменения, внесенные в httpd.conf :

append wsgi module:

LoadModule wsgi_module modules/mod_wsgi.so

добавить каталог в конфигурацию

<Directory "C:/testing">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

ссылка URL с каталогом

Alias /testapp "C:\testing"

ссылка URL с приложением wsgi

WSGIScriptAlias /testapp "C:\testing\invoke.wsgi"

Перезапустить веб-сервер.Go http://server_name/testapp Приложение должно показать идентификатор процесса и выйти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...