所以,我正在开发一个应用程序,它必须在每次启动时检查大约60 GB的数据。显然这需要并行化,我不希望应用程序挂在" LOADING ......"屏幕一分半钟。
我使用multiprocessing.Pool
' s map_async
来处理此问题;主线程调用map_async(checkfiles, path_hash_pairs, callback)
并提供一个回调函数,告诉它在发现不匹配时会发出警告。
麻烦是......没有任何反应。使用我的任务管理器查看Python进程显示它们会生成,然后立即终止而不进行任何工作。他们从不打印任何东西,当然也永远不会完成并打电话给回调。
这个缩小的例子也表现出同样的问题:
def printme(x):
time.sleep(1)
print(x)
return x**2
if __name__ == "__main__":
l = list(range(0,512))
def print_result(res):
print(res)
with multiprocessing.Pool() as p:
p.map_async(printme, l, callback=print_result)
p.join()
time.sleep(10)
运行它,......没有任何反应。为map_async
交换map
的工作方式完全符合预期。
我只是犯了一个愚蠢的错误或什么?
答案 0 :(得分:3)
让我们看看会发生什么:
您正在使用上下文管理器自动“关闭”Pool
,但重要的是,如果您查看Pool.__exit__
的源代码,您会发现:
def __exit__(self, exc_type, exc_val, exc_tb):
self.terminate()
只需拨打terminate
而不是close
。因此,您仍然需要明确关闭Pool
,然后关闭join
。
with multiprocessing.Pool() as p:
p.map_async(printme, l, callback=print_result)
p.close()
p.join()
但在这种情况下,使用上下文管理器毫无意义,只需使用普通表单:
p = multiprocessing.Pool()
p.map_async(printme, l, callback=print_result)
p.close()
p.join()
为什么它适用于map
?因为map
将阻止util,所有的工作都已完成。