multiprocessing.Pool.map_async似乎......什么都不做?

时间:2017-10-20 05:37:07

标签: python python-multiprocessing

所以,我正在开发一个应用程序,它必须在每次启动时检查大约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的工作方式完全符合预期。

我只是犯了一个愚蠢的错误或什么?

1 个答案:

答案 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,所有的工作都已完成。