我不会打电话concurrent.futures
更“先进”——这是一个simpler无论您使用多线程还是多进程作为底层并行化技巧,接口的工作原理都非常相同。
因此,就像几乎所有“更简单的界面”实例一样,涉及很多相同的权衡:它的学习曲线更浅,很大程度上只是因为可用的东西少得多to学习;但是,由于它提供的选项较少,因此最终可能会让您感到沮丧,而更丰富的界面则不会。
就 CPU 密集型任务而言,这还不够明确,没有多大意义。对于 CPython 下的 CPU 密集型任务,您需要多个进程而不是多个线程才能获得加速。但是,您获得多少加速(如果有)取决于您的硬件、操作系统的详细信息,尤其是您的特定任务需要多少进程间通信。在幕后,所有进程间并行化技巧都依赖于相同的操作系统原语 - 用于获取这些原语的高级 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
支持多种不同的做事方式,您可能没有意识到它有多么简单can直到你在学习曲线上取得了很大的进步。
同样,所有这些不同的方式既是优点也是缺点。它们是一种优势,因为在某些情况下可能需要灵活性。它们是一个弱点,因为“最好只有一种明显的方法来做到这一点”。一个项目专门(如果可能的话)坚持concurrent.futures
从长远来看,它可能会更容易维护,因为它的最小 API 的使用方式缺乏无端的新颖性。