繁体   English   中英

如何在 python 中使用 asyncio 运行并发操作?

[英]How to run concurrent operations using asyncio in python?

我想在 asyncio 中运行“N”个并发操作。 这是我的代码的一般布局。

def heavy_operation(): 
   # Heavy operation 1....N  I want to run concurrently.
for x in range (N) :
  heavy_operation() 

heavy_operation是我向 API 发出的GET请求。 几行字符串一次。 由于 N 接近 100,我的代码运行缓慢。

只要繁重的操作同时运行,不使用 for 循环的解决方案也可以。

如果您的繁重操作不是异步的(使用async def定义并实际等待 IO 操作),那么 asyncio 不会对您有多大好处,因为它是单线程的并且适合并行化 IO。 当并行化 CPU-bound 代码时,您可以直接使用线程,如下所示:

import concurrent.futures

with concurrent.futures.ThreadPoolExecutor() as pool:
    for i in range(N):
        pool.submit(heavy_operation)  # you can also add positional arguments

请注意,如果heavy_operation受 CPU 限制,由于GIL的原因,您的代码运行速度可能不会比顺序版本快。 在这种情况下,您可以尝试将ThreadPoolExecutor更改为ProcessPoolExecutor以在单独的 python 进程中运行heavy_operation

如果heavy_operation是IO 绑定的(例如,它使用requests下载http),最佳方法是通过将底层库切换到支持asyncio 的库来将其转换为异步,例如从requestsaiohttp 然后,您将使用asyncio.gather并行运行heavy_operation ,如此和其他地方所示。

话虽如此,我还要补充一点,实际上,生成 100 个线程(假设您希望所有请求并行运行)不会妨碍现代系统。 您只需将该数字传递给ThreadPoolExecutor构造函数,它就可以正常工作。 asyncio 的好处是您获得的解决方案:a) 实际可扩展,因为它同样适用于 10、100 或 10,000 个并发连接,b) 避免线程的许多陷阱,例如竞争条件,以及 c)自动提供其他好处,例如可靠的取消和超时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM