【发布时间】:2017-10-31 23:26:32
【问题描述】:
我目前处于重复调用并行代码并尝试减少与多处理相关的开销的情况。因此,请考虑以下示例,该示例故意不包含“昂贵”的计算:
import multiprocessing as mp
def f(x):
# toy function
return x*x
if __name__ == '__main__':
for x in range(500):
pool = mp.Pool(processes=2)
print(pool.map(f, range(x, x + 50)))
pool.close()
pool.join() # necessary?
此代码需要 53 秒,而顺序方法需要 0.04 秒。
第一个问题:在这种情况下,当只使用 pool.map() 时,我真的需要调用 pool.join() 吗?我找不到忽略它的任何负面影响,运行时间将下降到 4.8 秒。 (我知道省略 pool.close() 是不可能的,因为那时我们会泄漏线程。)
现在,虽然这将是一个很好的改进,但作为第一个答案,我可能会得到“好吧,首先不要在循环中创建池”。好的,没问题,但是并行化的代码实际上存在于实例方法中,所以我会使用:
class MyObject:
def __init__(self):
self.pool = mp.Pool(processes=2)
def function(self, x):
print(self.pool.map(f, range(x, x + 50)))
if __name__ == '__main__':
my_object = MyObject()
for x in range(500):
my_object.function(x)
这将是我最喜欢的解决方案,因为它可以在 0.4 秒内运行。
第二个问题:我应该在某处显式调用 pool.close()/pool.join()(例如在 MyObject 的析构函数中)还是当前代码足够? (如果重要的话:可以假设我的项目中只有几个长期存在的 MyObject 实例。)
【问题讨论】:
-
您不需要调用
pool.join(),因为它会阻塞,直到它开始处理可迭代参数的所有进程都完成......并且由于您不会调用它,因此没有必要对于pool.close()或者。 -
pool.close() 是必要的,否则我会收到“打开的文件太多”异常(在 Linux 上)
-
很高兴知道您已经回答了部分问题。
标签: python multiprocessing pool