2015-06-09 3 views
1

Я пытаюсь определить программу для получения запроса HTML для запуска процесса на моем сервере и оставить его там в качестве демона, пока другой вызов HTML не сообщит серверу, чтобы он его убил. Моя проблема заключается в том, что демон запускается после правильного ответа HTML.HTML-вызов, который вызывает подпроцесс daemon

Я использую основанный на флягах веб-сервер python. Я пробовал многопроцессорные и подпроцессорные модули python без каких-либо успехов, обычно основной процесс завершал и убивал подпроцесс, прежде чем он мог бы принести пользу.

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

У меня нет идей ... помогите пожалуйста?

Это код:

from flask import Flask, request, abort 
app = Flask(__name__) 

import sys, time 

def f(): 
    import subprocess as sub 
    p = sub.Popen(['/path/to/file.py']) 
    print "process created " + str(p.pid) # prints to log 

@app.route("/", methods = ['POST', 'GET']) 
def home(): 
    if request.method == "GET": 
    # return an HTML form with a 'Login' button 
    return """ 
     <!DOCTYPE html> 
     <html> 
     <head> 
     </head> 
     <body> 
      Testing Login 
      <form action = "/" method = "post"> 
      <input type="submit" value="Login"> 
      </form> 
     </body> 
     </html> 
     """ 

    elif request.method == "POST": 
    import sys 
    import multiprocessing as mp 
    try: 
     m = mp.Process(name = 'sub', target = f) 
     m.daemon = True 
     m.start() 
     time.sleep(1) # artifically wait 1 sec for m to trigger subprocess 
     return "Logged in!" 
    except: 
     return "error! <br> " + str(sys.exc_info()) 
    else: 
    abort(401) 
+0

["процесс демона" означает определенную вещь] (https://pypi.python.org/pypi/python-daemon/). Вы действительно хотите запустить демона (почему бы не простой фоновый процесс (возможно, 'close_fds = True' было бы достаточно))? Почему вы используете подпроцесс для запуска кода Python? Вы пробовали 'concurrent.futures',' celery'? – jfs

+0

@ J.F.Sebastian Мне нужен демон, так что процесс будет работать, как только будет выполнен запрос HTML, иначе потоки будут завершены после возврата вызова HTML. Я не вижу, как помогут дескрипторы закрытия файла? Я собираюсь посмотреть на concurrent.futures и сельдерей сейчас, спасибо! – Alex

+0

Процесс не-демона может также выдержать HTTP-запрос. Открытые файловые дескрипторы могут поддерживать сетевые подключения. – jfs

ответ

0

я отвечаю на мой собственный вопрос, чтобы закрыть его в случае, если кто-нибудь натыкается на это. Я не уверен, насколько это применимо для других, поскольку все мои проблемы могут быть связаны с настройкой моего сервера (nginx -> uwsgi -> Flask -> python 2.7)

Я пробовал то, что @JFSebastian упоминает в комментариях ; concurrent.futures (версия с поддержкой backported для python 2.7) не выполняла работу (процесс ждал завершения цикла и никогда не возвращал ответ на HTTP-запрос). celery Я не тестировал, поскольку это слишком показалось для этой цели.

Я также попробовал модуль daemons, который я нашел, но, помимо необходимости многого переделать в мой код, он (по какой-то причине я не мог понять) убил родительский процесс uwsgi.

Наконец, я пробовал аргумент close_fds=True в subprocess.Popen, как и предложил @F.Sebastian, и он работает, но когда я убил процесс, он становится зомби. Я также попробовал аргумент &, чтобы сказать, что Linux работает на фоне, он не сильно изменился, только убийство процесса немного чище.

Надеюсь, это поможет, если кому-то это интересно.

Смежные вопросы