gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 00:12:01 26 4
gpt4 key购买 nike

是一个类似的函数:

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/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com