Python等待一个带有循环的函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python等待一个带有循环的函数相关的知识,希望对你有一定的参考价值。
我使用Sanic作为服务器并尝试同时处理多个请求。
我已经使用了await for encode函数(我使用for循环来模拟做某事)但是当我在两个独立的控制台中尝试time curl http://0.0.0.0:8000/
时,它不会同时运行。
我搜索过谷歌,但只找到event_loop,但它是安排注册的conroutines。
我如何等待for循环以便不会阻止请求?
谢谢。
from sanic import Sanic
from sanic import response
from signal import signal, SIGINT
import asyncio
import uvloop
app = Sanic(__name__)
@app.route("/")
async def test(request):
# await asyncio.sleep(5)
await encode()
return response.json({"answer": "42"})
async def encode():
print('encode')
for i in range(0, 300000000):
pass
asyncio.set_event_loop(uvloop.new_event_loop())
server = app.create_server(host="0.0.0.0", port=8000)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(server)
signal(SIGINT, lambda s, f: loop.stop())
try:
loop.run_forever()
except:
loop.stop()
运行for i in range()
是阻止。如果你改变它以将你的await asyncio.sleep(5)
放入encode
方法,你会发现它按预期运行。
@app.route("/")
async def test(request):
await encode()
return response.json({"answer": "42"})
async def encode():
print('encode')
await asyncio.sleep(5)
当你调用await encode()
并且encode是一种阻塞方法时,它仍然会阻止因为你没有“等待”任何其他东西。你的线程仍然被锁定。
您还可以添加另一个工作人员:
app.create_server(worker=2)
尝试浏览this answer
由于异步处理程序实际上在事件循环中运行,因此它作为回调异步运行而不是并发运行。 loop.run_forever()将一遍又一遍地调用loop._run_once来运行所有已注册的事件,每个await将停止协程并将控制权返回到eventloop并且eventloop安排运行下一个事件。
所以基本上如果你不想在长时间运行的for循环中阻塞,你需要手动将控制权交给for循环中的eventloop,see the issue about relinquishing control:
async def encode():
print('encode')
for i in range(0, 300000000):
await asyncio.sleep(0)
这是来自Guido的quote:
asyncio.sleep(0)就是说 - 让任何其他任务运行然后再回到这里。
以上是关于Python等待一个带有循环的函数的主要内容,如果未能解决你的问题,请参考以下文章