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

问题描述 投票:0回答:1

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

我在网上搜索了 python 中实现并发的不同方法,我发现了多处理库、concurrenct.futures 的 ProcessPoolExecutor() 和 ThreadPoolExecutor() 以及 asyncio。让我困惑的是这些库之间的区别。特别是多处理库的作用,因为它有像 pool.apply_async 这样的方法,它也能完成 asyncio 的工作吗?如果是这样,为什么它被称为多处理,因为它是与 asyncio 实现并发的不同方法(多进程与协作多任务)?

python multithreading multiprocessing python-asyncio
1个回答
92
投票

我们来看看标准库提供的相关并发相关模块:

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

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

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

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

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

另请注意,asyncio 可以在 concurrent.futures 提供的线程或进程池中等待函数

executed
,因此它可以充当所有这些不同模型之间的粘合剂。这就是为什么 asyncio 经常被用来构建新的图书馆基础设施的部分原因。

© www.soinside.com 2019 - 2024. All rights reserved.