Python中的Concurrent.futures与多处理3

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

Python 3.2引入了Concurrent Futures,它似乎是旧版线程和multiprocessing模块的一些高级组合。

与旧的多处理模块相比,在CPU绑定任务中使用它有什么优缺点?

This article表示他们更容易合作 - 是这样吗?

python python-3.x multiprocessing
1个回答
106
投票

我不会将concurrent.futures称为“高级” - 它是一个更简单的接口,无论您使用多个线程还是多个进程作为底层并行化噱头,它的工作方式都非常相似。

因此,与几乎所有“简单界面”的实例一样,涉及的权衡也大致相同:它的学习曲线较浅,很大程度上只是因为可用的学习量较少;但是,因为它提供的选项较少,它最终可能会让您以更丰富的界面不会让您感到沮丧。

到目前为止,受CPU约束的任务仍然存在,而且这个任务太低,而且说得太有意义了。对于CPython下的CPU绑定任务,您需要多个进程而不是多个线程才有机会获得加速。但是,获得多少(如果有的话)加速取决于硬件,操作系统的细节,特别是您的特定任务需要多少进程间通信。在幕后,所有进程间并行化噱头都依赖于相同的操作系统原语 - 用于获取这些原语的高级API不是底线速度的主要因素。

编辑:示例

这是您引用的文章中显示的最终代码,但我添加了一个使其工作所需的import语句:

from concurrent.futures import ProcessPoolExecutor
def pool_factorizer_map(nums, nprocs):
    # Let the executor divide the work among processes by using 'map'.
    with ProcessPoolExecutor(max_workers=nprocs) as executor:
        return {num:factors for num, factors in
                                zip(nums,
                                    executor.map(factorize_naive, nums))}

这与使用multiprocessing完全相同:

import multiprocessing as mp
def mp_factorizer_map(nums, nprocs):
    with mp.Pool(nprocs) as pool:
        return {num:factors for num, factors in
                                zip(nums,
                                    pool.map(factorize_naive, nums))}

请注意,在Python 3.3中添加了使用multiprocessing.Pool对象作为上下文管理器的功能。

哪一个更容易使用?哈哈;-)他们基本相同。

一个不同之处在于,Pool支持这么多不同的做事方式,你可能不会意识到在你爬上学习曲线之前是多么容易。

同样,所有这些不同的方式都是力量和弱点。它们是一种优势,因为在某些情况下可能需要灵活性。它们是一个弱点,因为“最好只有一种明显的方法”。一个专门(如果可能的话)坚持concurrent.futures的项目从长远来看可能更容易维护,因为缺乏关于如何使用其简约API的无偿新颖性。

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