为并行进程提供共享的只读资源

Providing shared read-only ressources to parallel processes

我正在解决一个问题,该问题允许进行一些相当没有问题的并行化。我很难弄清楚什么合适。 Python 中提供了并行化机制。我在 MacOS 上使用 python 3.9。

我的管道是:

我可以做到以下几点:

import multiprocessing
common_input_1 = None
common_input_2 = None

def parallel_computation_1(individual_input):
    return sum(1 for i in common_input_1 if i == individual_input)

def parallel_computation_2(individual_input):
    return individual_input in common_input_2

def main():
    multiprocessing.set_start_method('fork')
    global common_input_1
    global common_input_2
    common_input_1      = [1, 2, 3, 1, 1, 3, 1]
    individual_inputs_1 = [0,1,2,3]
    individual_inputs_2 = [0,1,2,3,4]
    with multiprocessing.Pool() as pool:
        common_input_2 = pool.map(parallel_computation_1, individual_inputs_1)
    with multiprocessing.Pool() as pool:
        common_output = pool.map(parallel_computation_2, individual_inputs_2)
    print(common_output)

if __name__ == '__main__':
    main()

按照中的建议,我使用全局变量来共享数据。如果我使用 set_start_method('fork') 就可以了(这对我有用,但在 MacOS 上似乎有问题)。

请注意,如果我删除第二个 with multiprocessing.Pool() 以仅将一个池用于两个并行任务,事情将无法进行(进程看不到 common_input_2 的新值) .

除了使用全局变量对我来说似乎是糟糕的编码风格(是吗?这只是我的直觉)之外,我并不喜欢启动一个新池的需要,因为它引入了一些可能不必要的东西开销。

您如何看待这些担忧,尤其是。第二个?

有没有好的替代品?我看到我可以使用 multiprocessing.Array,但由于我的数据是列表的列表,我需要将它展平成一个列表并以某种重要的方式在 parallel_computation 中使用它。如果我的共享输入更复杂,我将不得不付出相当多的努力将其包装到 multiprocessing.Valuemultiprocessing.Array 中。

您可以在创建进程池之前定义和计算 output_1 作为全局变量;这样每个进程都可以访问数据;这不会导致任何内存重复,因为您没有更改该数据(写时复制)。

_output_1 = serial_computation()


def parallel_computation(input_2):
    # here you can access _output_1
    # you must not modify it as this will result in creating new copy in the child process
    ...


def main():
    input_2 = ...
    with Pool() as pool:
        output_2 = pool.map(parallel_computation, input_2)