使用 flask-aiohttp 的异步子进程
Posted
技术标签:
【中文标题】使用 flask-aiohttp 的异步子进程【英文标题】:asynchronous subprocess using flask-aiohttp 【发布时间】:2015-12-21 10:24:35 【问题描述】:我正在使用Flask
Web 服务器来为耗时的计算提供接口。为了提高性能,我想
-
以new subprocess 开始计算,以便能够使用多个 CPU 内核进行多个并发计算
使用
asyncio
让计算异步运行
为了从 Flask 调用 asyncio
协程,我开始使用 flask-aiohttp
,它非常适用于简单的延迟任务,如示例中所示。
但是,我无法从 Flask 内部调用异步子进程:
#!/usr/bin/env python3
# coding: utf-8
from flask import Flask
from flask.ext.aiohttp import AioHTTP, async
import asyncio
from asyncio.subprocess import PIPE
CALC_SCRIPT = './calc'
app = Flask(__name__)
aio = AioHTTP(app)
@app.route('/calc/<int:n>')
@async
def calc(n):
print('calc() called'.format(n))
create = asyncio.create_subprocess_exec(CALC_SCRIPT, str(n),
stdout=PIPE, stderr=PIPE)
print('create... ', end='')
process = yield from create
print('process created. !r, type='.format(process,
type(process)))
yield from process.wait()
print('process finished.')
# yields (stdout, stderr)
result = '\n'.join(ch.decode().rstrip() for ch in
(yield from process.communicate()) if ch)
return result
if __name__ == '__main__':
aio.run(app, debug=True)
进程正在创建,但永远不会返回:
GET http://127.0.0.1:5000/calc/5
calc(5) called
creating... process created. <Process 5647>,
type=<class 'asyncio.subprocess.Process'>
我做错了什么?
【问题讨论】:
我相信你已经考虑过了,但是 CALC_SCRIPT 是做什么的呢?您是否使用简单的函数进行测试,例如阶乘之类的? 这可能会有所帮助:***.com/questions/24541192/… 是的,CALC_SCRIPT
是用于测试目的的slow fibonacci script。我偶然发现了您链接到的那个问题,但我的 standalone version 运行良好。
process.wait()
是否会导致计算通过?您可以在视图函数之外创建一个asyncio.couroutine
,然后在视图函数中以与独立版本类似的方式调用它吗?
【参考方案1】:
原因:从子线程运行 asyncio 子进程有限制,请参阅 asyncio 文档Subprocess and threads。
详细信息:使用debug=True
,Flask-aiohttp 在由 Werkzeug 的run_with_reloader
启动的子线程中处理请求。关闭调试,您的代码将正常运行。
或者根据上面的文档,Flask-aiohttp 应该在调用run_with_reloader
之前添加对asyncio.get_child_watcher()
的调用。通过此调用,即使使用 debug=True
,您的代码也会运行。
【讨论】:
以上是关于使用 flask-aiohttp 的异步子进程的主要内容,如果未能解决你的问题,请参考以下文章