代码之家  ›  专栏  ›  技术社区  ›  Draconis

如何将带备忘录的调用与外部程序并行?

  •  0
  • Draconis  · 技术社区  · 6 年前

    我有一个用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语言的经验让我对破坏缓存的竞争环境保持警惕。

    什么是最好的,最蟒蛇的方式并行化这一阶段的处理?我想保留备忘录,因为删除它会增加四倍的运行时间。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Amadan    6 年前

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

    你也可以理解为什么这项任务要花这么长时间。如果 计算 是很重的,那是不可能的;但是如果 启动 是很重的(这是我在做这样的事情时经常有的经验)。在这种情况下,将另一个可执行文件封装成具有循环并可以通信(最容易的是Web服务)是非常有用的。这样就可以获得真正的每请求开销,完全避免了为每个请求生成一个新的子流程所带来的启动开销。

        2
  •  1
  •   new-dev-123    6 年前

    你可以用 multiprocessing 要并行启动函数,请使用 multiprocessing.Queue 使缓存在进程之间保持同步。