我正在尝试从GET请求的视图运行代码。此代码在新线程中执行,因为它需要一些时间才能运行。请注意,我没有加入线程,因为那样会导致视图挂起。
我试图从内部do_work函数重定向回到“ / task”路由,但是没有成功。我是否可以通过重定向将这些数据获取到视图中?我可以使用ajax请求来帮助我吗?
此视图当前设计的缺点是什么?
@app.route("/task", methods=["GET"])
def start_task():
def do_work(value):
import time; time.sleep(value)
return "finished"
thread = Thread(target=do_work, kwargs={'value': 5})
thread.start()
return "started"
答案 0 :(得分:0)
如果您想使用Python threading
模块,请使用以下解决方案:
import threading
from flask import Flask, jsonify
app = Flask(__name__)
tasks = []
results = []
def do_work(value, task_id, results):
import time; time.sleep(value)
results[task_id] = "finished task {}".format(task_id)
@app.route("/task", methods=["GET"])
def start_task():
new_task_id = len(tasks)
task = threading.Thread(target=do_work, kwargs={'value': 5, 'task_id': new_task_id, 'results': results})
task.start()
tasks.append(task)
results.append(None)
return jsonify({'task_id': new_task_id, 'total_tasks': len(tasks)})
@app.route("/task/<int:task_id>", methods=["GET"])
def task_status(task_id):
assert 0 <= task_id < len(tasks)
if tasks[task_id].is_alive():
return jsonify({'status': 'running'})
try:
tasks[task_id].join()
return jsonify({'status': 'finished', 'result': results[task_id]})
except RuntimeError:
return jsonify({'status': 'not started'})
if __name__ == '__main__':
app.run(host='0.0.0.0')
由于Thread.join()
不返回值,因此我使用了线程和结果列表的概念
这个answer。
此代码为每个任务创建一个端点。任务总数和新任务ID返回 JSON,因此您可以更轻松地利用AJAX。
但是要注意
Global Interpreter Lock
这使得所有Python线程都在单个内核上运行。一个更好的解决方案是使用
multiprocessing
模块,特别是Pool
类(请参见此answer)。