Python 3.2引入了Concurrent Futures,它似乎是旧版线程和多处理模块的一些高级组合.
与旧的多处理模块相比,在CPU绑定任务中使用它有什么优缺点?
这篇文章表明他们更容易合作 - 是这样吗?
我不会称之为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))}
请注意,multiprocessing.Pool
在Python 3.3中添加了将对象用作上下文管理器的功能.
哪一个更容易使用?哈哈;-)他们基本相同.
一个区别是Pool
支持做的事情,你可能不知道是多么容易的很多不同的方式可以是直到你攀上了学习曲线相当一路上扬.
同样,所有这些不同的方式都是力量和弱点.它们是一种优势,因为在某些情况下可能需要灵活性.它们是一个弱点,因为"最好只有一种明显的方法".一个专门(如果可能)坚持的项目concurrent.futures
从长远来看可能更容易维护,因为在其简约API的使用方式方面缺乏无端的新颖性.