Python 3中的Concurrent.futures与多处理

2024-04-23 19:16:24 发布

您现在位置:Python中文网/ 问答频道 /正文

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

与较旧的多处理模块相比,将其用于CPU绑定任务有哪些优点和缺点?

This article表明它们更容易使用-是这样吗?


Tags: 模块articlecputhis线程multiprocessingconcurrent优点
1条回答
网友
1楼 · 发布于 2024-04-23 19:16:24

我不会把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对象作为上下文管理器的功能。

哪一个比较容易用?LOL;-)它们基本上是一样的。

一个不同之处是Pool支持许多不同的做事方式,直到你在学习曲线上爬了很高的一段路,你可能才意识到这有多么容易。

同样,所有这些不同的方式都是一种优势和劣势。它们是一种力量,因为在某些情况下可能需要灵活性。它们是一个弱点,因为“最好只有一个显而易见的方法”。一个完全(如果可能的话)依赖于concurrent.futures的项目可能在长期内更容易维护,因为在如何使用它的极简API方面缺乏无端的新颖性。

相关问题 更多 >