python的多处理和concurrent.futures有什么区别?
作者:互联网
在python中实现多处理的一种简单方法是
from multiprocessing import Pool
def calculate(number):
return number
if __name__ == '__main__':
pool = Pool()
result = pool.map(calculate, range(4))
基于期货的另一种实现方式是
from concurrent.futures import ProcessPoolExecutor
def calculate(number):
return number
with ProcessPoolExecutor() as executor:
result = executor.map(calculate, range(4))
两种选择基本上都是相同的,但一个显着的区别是我们不必使用通常的if __name__ ==’__ main__’子句来保护代码.这是因为期货的实施照顾了这个还是我们有不同的原因?
更广泛地说,multiprocessing和concurrent.futures之间有什么区别?什么时候优先于另一个?
编辑:
我最初的假设是,如果__name__ ==’__ main__’只是多处理所必需的,那就错了.显然,对于Windows上的两种实现都需要这种保护,而在unix系统上则没有必要.
解决方法:
实际上你应该使用if__name__ ==“__ main__”守护ProcessPoolExecutor:它使用multiprocessing.Process来填充它的Pool,就像multiprocessing.Pool一样,所以关于可选择性的所有相同的警告(特别是在Windows上)等适用.
我相信ProcessPoolExecutor最终会取代multiprocessing.Pool,根据this statement made by Jesse Noller(一个Python核心贡献者),当被问及为什么Python有这两个API时:
Brian and I need to work on the consolidation we intend(ed) to occur
as people got comfortable with the APIs. My eventual goal is to remove
anything but the basic multiprocessing.Process/Queue stuff out of MP
and into concurrent.* and support threading backends for it.
目前,ProcessPoolExecutor与multiprocessing.Pool完全相同,使用更简单(更有限)的API.如果你可以使用ProcessPoolExecutor,那就使用它,因为我认为它更有可能在长期内得到增强.
请注意,您可以使用ProcessPoolExecutor进行多处理的所有帮助程序,如Lock,Queue,Manager等.使用multiprocessing.Pool的主要原因是您需要初始化程序/ initargs(尽管有一个open bug可以将这些添加到ProcessPoolExecutor中)或maxtasksperchild.或者您正在运行Python 2.7或更早版本,并且不希望安装(或要求您的用户安装)concurrent.futures的后端口.
编辑:
另外值得注意的是:根据this question,multiprocessing.Pool.map优于ProcessPoolExecutor.map.请注意,每个工作项的性能差异非常小,因此如果您在非常大的迭代上使用map,您可能只会注意到性能差异很大.性能差异的原因是multiprocessing.Pool将批处理传递的迭代映射到块,然后将块传递给工作进程,这减少了父和子之间IPC的开销. ProcessPoolExecutor总是一次将一个项目从iterable传递给子节点,由于IPC开销的增加,这会导致大型迭代的性能下降得更慢.好消息是这个问题将在Python 3.5中得到修复,因为chunksize关键字参数已被添加到ProcessPoolExecutor.map中,如果您知道自己正在处理大型迭代,则可以使用它来指定更大的块大小.有关详细信息,请参阅此bug.
标签:concurrent-futures,python,multiprocessing 来源: https://codeday.me/bug/20191005/1857408.html