使用昂贵的初始化优化 multiprocessing.Pool

Optimizing multiprocessing.Pool with expensive initialization

这是一个完整的简单工作示例

import multiprocessing as mp
import time
import random


class Foo:
    def __init__(self):
        # some expensive set up function in the real code
        self.x = 2
        print('initializing')

    def run(self, y):
        time.sleep(random.random() / 10.)
        return self.x + y


def f(y):
    foo = Foo()
    return foo.run(y)


def main():
    pool = mp.Pool(4)
    for result in pool.map(f, range(10)):
        print(result)
    pool.close()
    pool.join()


if __name__ == '__main__':
    main()

我如何修改它,使 Foo 只被每个工作人员初始化一次,而不是每个任务?基本上我希望 init 被调用 4 次,而不是 10 次。我正在使用 python 3.5

最明显的延迟加载

_foo = None
def f(y):
    global _foo
    if not _foo:
       _foo = Foo()
    return _foo.run(y)

处理此类事情的预期方法是通过 Pool() 构造函数的可选 initializerinitargs 参数。它们的存在恰恰是为了让您在创建工作进程时只做一次事情。因此,例如,添加:

def init():
    global foo
    foo = Foo()

并将 Pool 创建更改为:

pool = mp.Pool(4, initializer=init)

如果您需要将参数传递给每个进程的初始化函数,那么您还需要添加一个适当的 initargs=... 参数。

注意:当然你也应该删除

foo = Foo()

来自 f() 的行,以便您的函数 使用 init() 创建的全局 foo