使用昂贵的初始化优化 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()
构造函数的可选 initializer
和 initargs
参数。它们的存在恰恰是为了让您在创建工作进程时只做一次事情。因此,例如,添加:
def init():
global foo
foo = Foo()
并将 Pool
创建更改为:
pool = mp.Pool(4, initializer=init)
如果您需要将参数传递给每个进程的初始化函数,那么您还需要添加一个适当的 initargs=...
参数。
注意:当然你也应该删除
foo = Foo()
来自 f()
的行,以便您的函数 使用 由 init()
创建的全局 foo
。
这是一个完整的简单工作示例
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()
构造函数的可选 initializer
和 initargs
参数。它们的存在恰恰是为了让您在创建工作进程时只做一次事情。因此,例如,添加:
def init():
global foo
foo = Foo()
并将 Pool
创建更改为:
pool = mp.Pool(4, initializer=init)
如果您需要将参数传递给每个进程的初始化函数,那么您还需要添加一个适当的 initargs=...
参数。
注意:当然你也应该删除
foo = Foo()
来自 f()
的行,以便您的函数 使用 由 init()
创建的全局 foo
。