在函数内的循环内多处理循环

时间:2017-12-07 22:57:26

标签: python for-loop multiprocessing

我编写了一些代码来将for循环分解为多个进程以加速计算。

import numpy as np
import formfactors
from subdivide_loop import subdivide_loop
import multiprocessing


def worker(start, end, triangleI, areaI, scene, kdtree, samples, output):
    form_factors = np.zeros(end-start)
    for j in range(start, end):
        triangleJ = np.array(scene[j][0:4])
        form_factors[start] = formfactors.uniform(triangleJ, triangleI, areaI, kdtree, samples)
    result = output.get(block=True)
    for j in range(start, end):
        result[j] = form_factors[j]
    output.put(result)


def calculate_formfactors(start, end, triangleI, areaI, scene, kdtree, samples, output, nb_processes,
                          max_interval_length):
    intervals = subdivide_loop(start, end, max_interval_length, nb_processes)
    print("start")
    jobs = []
    for k in range(nb_processes):
        p = multiprocessing.Process(target=worker,
                                    args=(intervals[k][0], intervals[k][1], triangleI, areaI, scene, kdtree,
                                          samples, output))
        jobs.append(p)
    for p in jobs:
        p.start()
    for p in jobs:
        p.join()
    results = output.get()
    return results

我希望能够在循环内的函数内调用calculate_formfactors(),如下所示:

def outer_function():
    for i in range(1000):
        for j in range(i + 1, 1000, max_interval_length):
            form_factors = calculate_formfactors(args)

但是运行它会出错:

An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:

    if __name__ == '__main__':
        freeze_support()
        ...

由于外部函数的工作原理,不可能分解outer_function()而不是calculate_formfactors()。

那么,有关如何做到这一点的任何建议吗?

1 个答案:

答案 0 :(得分:0)

如错误所示,请确保从outer_function()后卫中调用__main__(或任何启动它),例如

if __name__ == "__main__":
    outer_function()

它不一定是outer_function(),但您需要将其全部追溯到初始化链的第一步,最终导致调用multiprocessing.Process()并将其置于上面块。

这是因为在非分叉系统中,多个进程基本上作为子进程运行,因此从主脚本创建新进程最终将产生无限递归/进程生成。您可以在this answer中详细了解相关信息。因此,您必须确保您的多处理初始化代码只执行一次__main__防护所在的位置。