2015-04-12 75 views
0

下面的代碼在某個URL(/ new ...)上執行並將變量分配給會話cookie,該cookie用於構建顯示。這個例子使用subprocess.Popen調用一個命令。Python瓶,處理Popen輪詢/等待/溝通,無需停止多線程Python

問題是,下面調用的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,包括瓶0.10.1

回答

1

首先,你應該使用像芹菜,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('/') 

現在,它不會擋住你的視線! :)