asyncio,将普通函数包装为异步 [英] asyncio, wrapping a normal function as asynchronous

查看:142
本文介绍了asyncio,将普通函数包装为异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

功能类似于:

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

await f(5)

适当地异步/非阻塞?

asyncio提供的睡眠功能是否有所不同?

Is the sleep function provided by asyncio any different?

最后,aiorequests是否是可行的异步替代请求?

and finally, is aiorequests a viable asynchronous replacement for requests?

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

(to my mind it basically wraps main components as asynchronous)

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

推荐答案

提供的函数不是正确编写的异步函数,因为它会调用 blocking 调用,该调用在asyncio中被禁止.(快速提示协程"存在问题,因为它不包含单个 await .)被禁止的原因是诸如 sleep之类的阻塞调用()将暂停当前线程,而不会给其他协程一个运行的机会.换句话说,它不会暂停当前的协程,而是会暂停整个事件循环,即所有协程.

The provided function is not a correctly written async function because it invokes a blocking call, which is forbidden in asyncio. (A quick hint that there's something wrong with the "coroutine" is that it doesn't contain a single await.) The reason that it is forbidden is that a blocking call such as sleep() will pause the current thread without giving other coroutines a chance to run. In other words, instead of pausing the current coroutine, it will pause the whole event loop, i.e. all coroutines.

在asyncio(和其他异步框架)中,诸如 time.sleep()之类的阻塞原语被诸如

In asyncio (and other async frameworks) blocking primitives like time.sleep() are replaced with awaitables like asyncio.sleep(), which suspend the awaiter and resume it when the time is right. Other coroutines and the event loop are not only unaffected by suspension of a coroutine, but that's precisely when they get the chance to run. Suspension and resumption of coroutines is the core of async-await cooperative multitasking.

Asyncio支持在单独的线程中运行旧式阻止功能,因此它们不会阻止事件循环.这是通过调用 run_in_executor 来实现的> ,这会将执行移交给线程池(执行器,用Python的

Asyncio supports running legacy blocking functions in a separate thread, so that they don't block the event loop. This is achieved by calling run_in_executor which will hand off the execution to a thread pool (executor in the parlance of Python's concurrent.futures module) and return an asyncio awaitable:

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() 之类的本机asyncio函数不使用这种方法;他们直接告诉事件循环以暂停它们以及如何唤醒它们(

This is the technique used by aiorequests to wrap request's blocking functions. Native asyncio functions like asyncio.sleep() do not use this approach; they directly tell the event loop to suspend them and how to wake them up (source).

run_in_executor 对于快速包装遗留的阻塞代码很有用,并且非常有效.由于某些原因,它总是不如本地异步实现:

run_in_executor is useful and effective for quick wrapping of legacy blocking code, and not much else. It is always inferior to a native async implementation, for several reasons:

  • 它没有实现取消.与线程不同,异步任务是完全可取消的,但这不会扩展到共享线程限制的 run_in_executor .

它不提供轻量级任务,这些任务可能数以万计并并行运行. run_in_executor 在后台使用线程池,因此,如果您等待的功能超过最大数量的工作人员,则某些功能将不得不等待其轮流才能开始工作.另一种选择是增加工作人员的数量,这将使操作系统占用太多线程.Asyncio允许并行操作的数量与您使用 poll 侦听事件的手写状态机中的操作相匹配.

It doesn't provide light-weight tasks which may number in tens of thousands and run in parallel. run_in_executor uses a thread pool under the hood, so if you await more functions than the maximum number of workers, some functions will have to wait their turn to even start working. The alternative, to increase the number of workers, will swamp the OS with too many threads. Asyncio allows the number of parallel operations to match what you'd have in a hand-written state machine using poll to listen for events.

它可能与更复杂的API不兼容,例如那些公开用户提供的回调,迭代器或提供自己的基于线程的异步功能的API.

It is likely incompatible with more complex APIs, such as those that expose user-provided callbacks, iterators, or that provide their own thread-based async functionality.

建议避免像aiorequests这样的拐杖,直接进入 aiohttp .该API与请求的API非常相似,并且使用起来几乎令人愉快.

It is recommended to avoid crutches like aiorequests and dive directly into aiohttp. The API is very similar to that of requests, and it is almost as pleasant to use.

这篇关于asyncio,将普通函数包装为异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆