【问题标题】:Python await a function with loop insidePython等待一个内部有循环的函数
【发布时间】:2018-03-04 10:37:24
【问题描述】:

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

我已经将 await 用于编码功能(我使用 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()

【问题讨论】:

    标签: python python-3.x web parallel-processing sanic


    【解决方案1】:

    运行 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

    【讨论】:

      【解决方案2】:

      由于异步处理程序实际上是在事件循环中运行,它作为回调异步运行而不是并发运行。 loop.run_forever() 会一遍又一遍地调用 loop._run_once 来运行所有注册的事件,每次等待都会停止协程并将控制权返回给 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) 意味着——让任何其他任务运行,然后 回来吧。

      【讨论】:

        猜你喜欢
        • 2021-04-07
        • 1970-01-01
        • 1970-01-01
        • 2012-10-07
        • 1970-01-01
        • 2018-08-04
        • 2014-08-15
        • 2019-07-02
        • 2023-01-20
        相关资源
        最近更新 更多