Python 3中的Concurrent.futures与Multiprocessing


Answers:


145

我不会称其为concurrent.futures“高级”,它是一个更简单的接口,其工作原理几乎相同,无论您使用多个线程还是多个进程作为基础并行化ization头。

所以,像“简单的界面”的几乎所有情况下,大同小异的取舍都参与:它有一个浅的学习曲线,这在很大程度上只是因为有可用的要少得多,以学习; 但是,由于它提供的选项较少,最终可能会以丰富的界面无法实现的方式使您感到沮丧。

就与CPU绑定的任务而言,这还不够具体,以至于说不出什么意义。对于CPython下与CPU绑定的任务,您需要多个进程而不是多个线程才能获得加速的机会。但是,获得多少加速(如果有)取决于硬件,操作系统的详细信息,尤其取决于特定任务需要多少进程间通信。在幕后,所有进程间并行化头都依赖于相同的OS原语-用于获得这些原语的高级API并不是底线速度的主要因素。

编辑:示例

这是您引用的文章中显示的最终代码,但是我添加了一个导入语句以使其正常工作:

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))}

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

哪一个更容易使用?大声笑;-)他们本质上是相同的。

一个区别是Pool支持这样的事情,你可能不知道是多么容易的许多不同的方式可以是直到你攀上了学习曲线相当一路上扬。

同样,所有这些不同的方式都是优点和缺点。它们是优势,因为在某些情况下可能需要灵活性。它们之所以成为弱点,是因为“最好只有一种明显的方法”。concurrent.futures从长远来看,专案(如果可能)坚持下去的项目可能会更容易维护,因为在如何使用其最小限度的API方面缺乏免费的新颖性。


20
“您需要多个进程而不是多个线程才能获得加速的机会”,这太苛刻了。如果速度很重要;该代码可能已经使用了C库,因此可以释放GIL,例如regex,lxml,numpy。
jfs 2013年

4
@JFSebastian,感谢您的补充-也许我应该说“在 CPython下”,但是恐怕没有讨论GIL的简短解释方法了。
蒂姆·彼得斯

2
值得一提的是,在使用长IO进行操作时,线程可能特别有用且足够。
kotrfa '16

9
@TimPeters在某些方面ProcessPoolExecutor实际上具有更多的选择,Pool因为ProcessPoolExecutor.submit返回Future允许取消的实例(cancel),检查引发了哪个异常(exception),并在完成时动态添加要调用的回调(add_done_callback)。AsyncResult由返回的实例无法使用这些功能Pool.apply_async。在其他方面Pool做出了应有的更多选项initializer/ initargsmaxtasksperchildcontextPool.__init__,多方法,通过暴露的Pool实例。
最多

2
@max,当然,但是请注意,问题不是关于Pool,而是关于模块的。 Pool只是其中的一小部分multiprocessing,而且在文档中如此之低,人们需要一段时间才能意识到它甚至存在于中multiprocessing。这个特定的答案侧重于此,Pool因为这是OP链接到的所有文章,并且cf“使用起来容易得多”,对于该文章所讨论的内容根本不正确。除此之外,cfas_completed()也可以很方便的。
蒂姆·彼得斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.