python-3.x - asyncio,将普通函数包装为异步

标签 python-3.x asynchronous python-requests wrapper python-asyncio

是一个类似的函数:

async def f(x):
    time.sleep(x)

await f(5)

适当的异步/非阻塞?

asyncio 提供的 sleep 功能有什么不同吗?

最后,aiorequests 是一个可行的异步请求替代品吗?

(在我看来,它基本上将主要组件包装为异步)

https://github.com/pohmelie/aiorequests/blob/master/aiorequests.py

最佳答案

提供的函数不是正确编写的异步函数,因为它调用了阻塞调用,这在 asyncio 中是被禁止的。 (“协程”有问题的一个快速提示是它不包含单个 await 。)禁止它的原因是阻塞调用,例如 sleep()将暂停当前线程,而不给其他协程运行的机会。换句话说,它不会暂停当前协程,而是暂停整个事件循环,即 全部 协程。
在 asyncio(和其他异步框架)中,阻塞原语如 time.sleep()替换为 asyncio.sleep() 等可等待对象,它暂停等待者并在适当的时候恢复它。其他协程和事件循环不仅不受协程暂停的影响,而且恰恰是它们有机会运行的时候。协程的挂起和恢复是 async-await 协作多任务的核心。
Asyncio 支持在单独的线程中运行遗留的阻塞函数,这样它们就不会阻塞事件循环。这是通过调用 run_in_executor 来实现的。这会将执行移交给线程池(用 Python 的 concurrent.futures 模块的说法是执行器)并返回 asyncio 等待:

async def f(x):
    loop = asyncio.get_event_loop()
    # start time.sleep(x) in a separate thread, suspend
    # the current coroutine, and resume when it's done
    await loop.run_in_executor(time.sleep, x)
这是 aiorequests 用来包装请求的阻塞函数的技术。原生异步函数,如 asyncio.sleep() 不要使用这种方法 ;它们直接告诉事件循环暂停它们以及如何唤醒它们(source)。run_in_executor对于快速包装遗留阻塞代码非常有用且有效,仅此而已。由于以下几个原因,它总是不如原生异步实现:
  • 它不实现取消。与线程不同,异步任务是完全可取消的,但这不会扩展到 run_in_executor ,它共享线程的限制。
  • 它不提供可能数以万计并并行运行的轻量级任务。 run_in_executor在后台使用线程池,因此如果您等待的函数多于最大工作线程数,则某些函数将不得不等待轮到它们才能开始工作。另一种方法是增加工作人员的数量,会用太多的线程淹没操作系统。 Asyncio 允许并行操作的数量与您在使用 poll 的手写状态机中所拥有的数量相匹配。监听事件。
  • 它可能与更复杂的 API 不兼容,例如那些公开用户提供的回调、迭代器或提供自己的基于线程的异步功能的 API。

  • 建议避免使用airequests之类的拐杖,直接潜入aiohttp . API 与请求的 API 非常相似,使用起来几乎一样愉快。

    关于python-3.x - asyncio,将普通函数包装为异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57336602/

    相关文章:

    python - 了解非 bool 运算符在 bool 值上的使用

    django - 与 factory boy 和 pytest 一起使用的自定义 faker 提供程序

    javascript - 如何从异步调用返回响应?

    c# - 异步,只有一个等待

    python - 从 Flask 返回 requests.Response 对象

    python - 使用 Python 将 ".wav"文件发送到 URL,打印 Response How To?

    python - input() 在 Spyder IDE 中带有感叹号 (!)

    python - 在 Python 中,我们应该在参数列表中设置 Optional[str] = None 吗?

    javascript - Async-await 'Promise {<pending>} with Array.prototype.map

    python - 请求、请求 2 和请求 3 之间有什么区别?