python-asyncio - 使用替代事件循环而不设置全局策略

标签 python-asyncio uvloop

我正在使用 uvloop websockets 作为

import uvloop
coro = websockets.serve(handler, host, port)  # creates new server
loop = uvloop.new_event_loop()
loop.create_task(coro)
loop.run_forever()

它工作正常,我只是想知道我是否可以在不设置全局 asyncio 的情况下遇到一些意想不到的问题。政策到 uvloop .据我了解,只要没有任何内容不使用全局 asyncio,就应该不设置全局策略。方法,但直接与传递的事件循环一起使用。那是对的吗?

最佳答案

asyncio 中有三个主要的全局对象:

  • 政策(所有线程通用)
  • 默认循环(特定于当前线程)
  • 运行循环(特定于当前线程)

  • 所有在 asyncio 中获取当前上下文的尝试都通过一个函数,asyncio.get_event_loop .

    要记住的一件事是 since Python 3.6 (和 Python 3.5.3+),get_event_loop有一个特定的行为:
  • 如果在循环运行时调用它(例如在协程中),则返回运行循环。
  • 否则,策略将返回默认循环。

  • 示例 1:
    import uvloop
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    loop = asyncio.get_event_loop()
    loop.run_forever()
    

    这里的策略是 uvloop 策略。 get_event_loop 返回的循环是一个 uvloop,它被设置为这个线程的默认循环。当这个循环运行时,它被注册为运行循环。

    在本例中,调用 get_event_loop()该线程中的任何地方都返回正确的循环。

    示例 2:
    import uvloop
    loop = uvloop.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_forever()
    

    这里的策略仍然是默认策略。 new_event_loop 返回的循环是一个 uvloop,并使用 asyncio.set_event_loop 显式设置为该线程的默认循环.当这个循环运行时,它被注册为运行循环。

    在本例中,调用 get_event_loop()该线程中的任何地方都返回正确的循环。

    示例 3:
    import uvloop
    loop = uvloop.new_event_loop()
    loop.run_forever()
    

    这里的策略仍然是默认策略。 new_event_loop 返回的循环是一个 uvloop,但它没有被设置为这个线程的默认循环。当这个循环运行时,它被注册为运行循环。

    在本例中,调用 get_event_loop()在协程中返回正确的循环(正在运行的 uvloop)。但是打电话get_event_loop()在协程之外将导致一个新的标准 asyncio 循环,设置为该线程的默认循环。

    所以前两种方法很好,但不鼓励第三种方法。

    关于python-asyncio - 使用替代事件循环而不设置全局策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44000136/

    相关文章:

    python - 如何将第三方库中的函数转换为异步函数?

    python 无法使用 HTTP 请求从异步函数获取返回值

    python - 如何从 asyncio 中的信号处理程序捕获自定义异常?

    python - aiohttp + uvloop 并行 HTTP 请求比没有 uvloop 慢

    python - 使用 asyncio 将数据从任务获取到连接

    python3 - 从异步方法获取结果

    python - 在长时间运行的代码中使用 asyncio.sleep() 将异步函数划分为多个较小的代码部分是否合适?

    cython - 如何从 C 访问 asyncio/uvloop 循环

    python - 如何使用asyncio python中的子进程模块限制并发进程数