Python等待一个包含循环的函数

2024-06-09 05:23:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Sanic作为服务器,并尝试同时处理多个请求。在

我使用了await for the encode函数(我使用for loop来模拟执行某些操作),但是当我在两个独立的控制台中尝试time curl http://0.0.0.0:8000/时,它不会同时运行。在

我搜索过google,但只找到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()

Tags: fromimportloopeventasyncioappforsignal
2条回答

由于异步处理程序实际上是在eventloop中运行的,所以它以回调的形式异步运行,而不是并发地运行。 循环。永远运行()将调用loop。如果要运行所有已注册的事件,请反复运行,每次wait都将停止协程并将控制权交回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) means just that let any other tasks run and then come back here.

正在运行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是一个阻塞方法时,它仍然会阻塞,因为您没有“等待”其他任何东西。你的线还锁着。在

您还可以添加另一个工人:

^{pr2}$

试试看this answer

相关问题 更多 >