Python 使用ProcessPoolExecutor进行并行处理

Python 使用ProcessPoolExecutor进行并行处理,python,process-pool,Python,Process Pool,我有一个巨大的元素列表,必须以某种方式进行处理。 我知道可以通过多处理的过程来完成: pr1 = Process(calculation_function, (args, )) pr1.start() pr1.join() 所以我可以创建10个进程,并将参数除以10传递给args。然后工作就完成了 但我不想手动创建它并手动计算它。相反,我想使用,我是这样做的: executor = ProcessPoolExecutor(max_workers=10) executor.map(calcula

我有一个巨大的元素列表,必须以某种方式进行处理。 我知道可以通过多处理的过程来完成:

pr1 = Process(calculation_function, (args, ))
pr1.start()
pr1.join()
所以我可以创建10个进程,并将参数除以10传递给args。然后工作就完成了

但我不想手动创建它并手动计算它。相反,我想使用,我是这样做的:

executor = ProcessPoolExecutor(max_workers=10)
executor.map(calculation, (list_to_process,))
计算是我做这项工作的功能

def calculation(list_to_process):
    for element in list_to_process:
        # .... doing the job
列表到进程是我要处理的列表

但在运行此代码之后,循环上的迭代只进行一次。 我以为

executor = ProcessPoolExecutor(max_workers=10)
executor.map(calculation, (list_to_process,))
与此相同10次:

pr1 = Process(calculation, (list_to_process, ))
pr1.start()
pr1.join()
但这似乎是错误的


如何通过ProcessPoolExecutor实现真正的多处理?

计算
函数中删除
for
循环。现在您正在使用
ProcessPoolExecutor.map
,调用
map()
就是您的循环,区别在于列表中的每个元素都被发送到不同的进程。例如

def calculation(item):
    print('[pid:%s] performing calculation on %s' % (os.getpid(), item))
    time.sleep(5)
    print('[pid:%s] done!' % os.getpid())
    return item ** 2

executor = ProcessPoolExecutor(max_workers=5)
list_to_process = range(10)
result = executor.map(calculation, list_to_process)
您将在终端中看到如下内容:

[pid:23988] performing calculation on 0
[pid:10360] performing calculation on 1
[pid:13348] performing calculation on 2
[pid:24032] performing calculation on 3
[pid:18028] performing calculation on 4
[pid:23988] done!
[pid:23988] performing calculation on 5
[pid:10360] done!
[pid:13348] done!
[pid:10360] performing calculation on 6
[pid:13348] performing calculation on 7
[pid:18028] done!
[pid:24032] done!
[pid:18028] performing calculation on 8
[pid:24032] performing calculation on 9
[pid:23988] done!
[pid:10360] done!
[pid:13348] done!
[pid:18028] done!
[pid:24032] done!
虽然事件的顺序实际上是随机的。由于某种原因,返回值(至少在我的Python版本中)实际上是一个对象。但这是一个实现细节。您可以将结果作为列表返回,如下所示:

>>> list(result)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

在您的示例代码中,您传递了一个元素元组
(list\u to\u process,
),因此这将把您的完整列表传递给一个进程。

谢谢您的回复!我不完全明白。。列表到进程的迭代应该在哪里?因此,我必须在中使用列表中的一个元素-loop@John在任何地方,
executor.map
allready都会对列表中的每个元素进行迭代,并将其作为参数应用到我解释过的计算函数中,迭代是由
ProcessPoolExecutor.map()
执行的。这基本上等同于:
对于列表中的项到过程:计算(项)
,除了在不同的过程中可以为每个项调用
计算
。使用内置函数并确保您了解其工作原理
ProcessPoolExecutor.map
也在做同样的事情,但每次计算都被分配到不同的进程,然后结果以正确的顺序收集起来。非常感谢您的帮助!帮了我大忙。另外,给处于类似情况的任何人一个提示。此“map()”包含多个iterable,迭代器在最短iterable耗尽时停止。因此,如果有一个参数对于所有循环都是常量,则需要引用此参数: