如何并行化对外部程序的记忆调用?

时间:2019-07-08 06:14:57

标签: python multithreading parallel-processing python-multiprocessing python-multithreading

我有一个用Python编写的数据处理程序,需要在一个阶段中调出外部程序。分析表明,在这一阶段中花费了大约50%的总处理时间。

我有一台具有多核的计算机,因此并行性似乎是解决方案。问题是,该呼叫已记录:

def one_stage_of_processing(long_list_of_inputs, cache={}):
    outputs = []
    for input in list_of_inputs:
        outputs.append(expensive_external_processing(input, cache))
    return outputs

def expensive_external_processing(input, cache):
    if input not in cache:
        cache[input] = subprocess.run(...).stdout
    return cache[input]

使用C的经验使我警惕竞争条件会损坏缓存。

并行处理此阶段的最佳,最Pythonic方法是什么?我想保留备忘录,因为删除备忘录会使运行时间增加四倍。

2 个答案:

答案 0 :(得分:1)

您可以异步启动任务,然后将future放入备忘录中。询问备忘录结果的任何人都将遇到以下三种状态之一:无备忘录(因此启动新的昂贵的外部处理任务),未完成的未来备忘录(您可以等待它,或者确认它尚未完成,然后再做其他事情直到完成),或完成将来的备忘(结果立即可用)。这样,您可以避免在处理完成之前发出多个相同的请求。请注意,期货仅从3.5开始可用。

您还可以看到为什么任务需要这么长时间。如果计算很繁琐,那就没有办法解决;但是如果 startup 很沉重(在执行此类操作时,这通常是我的经验。在这种情况下,将另一个可执行文件包装到具有循环并可以通信的内容中非常有用(大多数轻松,这是一个Web服务。)这使您拥有真正的每次请求成本,完全避免了通过为每个请求生成一个新的子流程而获得的启动成本。

答案 1 :(得分:1)

您可以使用multiprocessing来并行启动功能,然后使用multiprocessing.Queue来使进程之间的缓存保持同步。