python中多处理,异步和concurrency.futures之间的区别

Posted

技术标签:

【中文标题】python中多处理,异步和concurrency.futures之间的区别【英文标题】:Difference between multiprocessing, asyncio, threading and concurrency.futures in python 【发布时间】:2020-04-21 19:39:57 【问题描述】:

刚开始使用并发,我对何时使用不同的 python 并发库感到困惑。据我了解,多处理、多线程和异步编程是并发的一部分,而多处理是称为并行的并发子集的一部分。

我在网上搜索了有关在 python 中处理并发的不同方法,我发现了多处理库 concurrenct.futures 的 ProcessPoolExecutor() 和 ThreadPoolExecutor() 以及 asyncio。让我感到困惑的是这些库之间的区别。尤其是多处理库的作用,因为它具有诸如 pool.apply_async 之类的方法,它是否也可以完成 asyncio 的工作?如果是这样,当它是与 asyncio 实现并发的不同方法(多进程 vs 协作多任务)时,为什么要称为多处理?

【问题讨论】:

multiprocessing 使用进程。 threading 使用线程。 asyncio 使用事件循环。进程更适合 CPU 密集型任务,不受 GIL 约束。线程和事件循环更适合 I/O 密集型任务。 concurrent.futures 是在 multiprocessingthreading 之上的抽象。 multiprocessingasyncio之间没有联系。 【参考方案1】:

有几个不同的库在起作用:

threading:操作系统级线程的接口。请注意,受 CPU 限制的工作主要由 GIL 序列化,因此不要期望计算速度会加快。当您需要并行调用阻塞 API 以及需要精确控制线程创建时使用它。避免创建太多线程(例如数千个),因为它们不是免费的。如果可能,不要自己创建线程,而是使用concurrent.futures

multiprocessing:使用类似于threading 的 API 生成多个 python 进程的接口。多个进程并行工作,因此您实际上可以使用此方法加快计算速度。缺点是如果不使用特定于多处理的tools,您将无法共享内存中的数据结构。

concurrent.futuresthreadingmultiprocessing 的现代接口,提供方便的线程/进程池调用执行器。池的主要入口点是submit 方法,它返回一个handle,您可以测试它是否完成或等待其结果。获取结果会为您提供提交函数的返回值并正确传播引发的异常(如果有),这对于 threading 来说会很乏味。 在考虑基于线程或进程的并行性时,concurrent.futures 应该是首选工具。

asyncio:虽然前面的选项是“异步”的,因为它们提供了非阻塞 API(这是apply_async 和其他人所指的),但它们仍然依赖于线程/进程池来发挥它们的魔力,并且不能真正并行地做比池中的工人更多的事情。 Asyncio 全面使用单线程执行和异步系统调用。它根本没有阻塞调用,唯一的阻塞部分是asyncio.run() 入口点。 Asyncio 代码通常使用协程编写,协程使用await 暂停直到发生有趣的事情。 (挂起与阻塞不同,它允许事件循环线程在您等待时继续执行其他操作。)与基于线程的解决方案相比,它具有许多优点,例如能够在没有使系统陷入困境,并且能够取消任务或轻松地一次等待多个事情。 Asyncio 应该是服务器和连接到多个服务器的客户端的首选工具。

在异步和多线程/多处理之间进行选择时,请考虑“线程用于并行工作,异步用于并行等待”的格言。

还请注意,asyncio 可以在concurrent.futures 提供的线程或进程池中等待函数executed,因此它可以充当所有这些不同模型之间的粘合剂。这也是为什么 asyncio 经常被用于构建新的图书馆基础设施的部分原因。

【讨论】:

以上是关于python中多处理,异步和concurrency.futures之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

python异步并发模块concurrent.futures入门详解

122 python程序中的线程操作-concurrent模块

每行文件的异步 HTTP API 调用 - Python

Python Day37 python多线程标准模块concurrent.futures

Python程序中的线程操作-concurrent模块

python 非常简单的接口,用于python中多处理函数的执行。