Python Flask,处理Popen轮询/等待/通信而不停止多线程Python

时间:2015-04-12 21:55:40

标签: python flask subprocess python-multithreading

以下代码在某个URL(/ new ...)上执行,并将变量分配给会话cookie,用于构建显示。此示例使用subprocess.Popen。

调用命令

问题是下面调用的Popen命令通常需要3分钟 - 而subprocess.communicate等待输出 - 在此期间所有其他Flask调用(例如另一个用户连接)都将暂停。我有一些注释行与我尝试过的其他事情没有成功 - 一个使用线程模块,另一个使用subprocess.poll。

from app import app
from flask import render_template, redirect, session
from subprocess import Popen, PIPE
import threading


@app.route('/new/<number>')
def new_session(number):
    get_list(number)
    #t = threading.Thread(target=get_list, args=(number))
    #t.start()
    #t.join()

    return redirect('/')

def get_list(number):
    #1 Call JAR Get String
    command = 'java -jar fetch.jar' + str(number)
    print "Executing " + command
    stream=Popen(command, shell=False, stdout=PIPE)

    #while stream.poll() is None:
    #    print "stream.poll = " + str(stream.poll())
    #    time.sleep(1)
    stdout,stderr = stream.communicate()

    #do some item splits and some processing, left out for brevity
    session['data'] = stdout.split("\r\n")

    return

正确处理这种情况的“更好的做法”是什么?

作为参考,此代码在win32上的Python 2.7.8中运行,包括Flask 0.10.1

1 个答案:

答案 0 :(得分:2)

首先,您应该使用像Celery,RabbitMQ或Redis这样的工作队列(这里是helpful hint)。

然后,定义get_list函数变为:

@celery.task
def get_list(number):
    command = 'java -jar fetch.jar {}'.format(number)
    print "Executing " + command
    stream = Popen(command, shell=False, stdout=PIPE)
    stdout, stderr = stream.communicate()
    return stdout.split('\r\n')

在你看来,你等待结果:

@app.route('/new/<number>')
def new_session(number):
    result = get_list.delay(number)
    session['data'] = result.wait()
    return redirect('/')

现在,它不会阻止您的观点! :)