【问题标题】:Multiprocessing a loop inside a loop inside a function多处理函数内循环内的循环
【发布时间】:2017-12-07 22:57:26
【问题描述】:

我编写了一些代码来将 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() 是不可能的。

那么,对于如何做到这一点有什么建议吗?

【问题讨论】:

    标签: python for-loop multiprocessing


    【解决方案1】:

    正如错误提示的那样,确保你的 outer_function()(或任何启动它的东西)是从 __main__ 守卫内调用的,例如

    if __name__ == "__main__":
        outer_function()
    

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

    这是因为在非分叉系统上,多个进程本质上是作为子进程运行的,因此从主脚本创建新进程最终会导致无限递归/进程产生。您可以在this answer 中阅读更多相关信息。因此,您必须确保您的多处理初始化代码只执行一次,这就是 __main__ 守卫的用武之地。

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 1970-01-01
      • 2021-09-17
      • 2019-09-27
      • 2013-09-09
      • 1970-01-01
      相关资源
      最近更新 更多