【问题标题】:Python 3: create new process when another one finishesPython 3:当另一个进程完成时创建新进程
【发布时间】:2017-11-07 19:45:43
【问题描述】:

我有一个数据数组要处理和处理,这些数据执行时间很长(1-2 分钟)并且需要大量内存进行计算。

raw = ['a', 'b', 'c']

def handler():
    # do something long

由于处理程序需要大量内存,我想在单独的子进程中执行它并在执行后将其杀死以释放内存。类似于下面的 sn-p:

from multiprocessing import Process
for r in raw:
    process = Process(target=handler, args=(r))
    process.start()

问题是这种方法会导致立即运行len(raw) 进程。这并不好。 此外,不需要在子流程之间交换任何类型的数据。因此,只需运行它们。 因此,最好同时运行几个进程并在现有进程完成后添加一个新进程。

如何实现(如果可能的话)?

【问题讨论】:

  • 在进程之间提供睡眠时间有帮助吗?
  • 为什么不在循环中调用process.join()?这样您就可以在每个过程之后等待。
  • @ChetanVasudevan,理论上可以,但我想这样的解决方案并不优雅,因为处理程序的执行时间不是恒定的

标签: python-3.x python-multiprocessing


【解决方案1】:

要按顺序运行您的流程,只需 join 循环中的每个流程:

from multiprocessing import Process
for r in raw:
    process = Process(target=handler, args=(r))
    process.start()
    process.join()

这样你就可以确定只有一个进程同时运行(没有并发)

这是最简单的方法。要运行多个进程但限制同时运行的进程数,可以使用multiprocessing.Pool 对象和apply_async

我构建了一个简单的示例,它计算参数的平方,并模拟繁重的处理:

from multiprocessing import Pool
import time

def target(r):
    time.sleep(5)
    return(r*r)
raw = [1,2,3,4,5]

if __name__ == '__main__':
    with Pool(3) as p:  # 3 processes at a time
        reslist = [p.apply_async(target, (r,)) for r in raw]
        for result in reslist:
            print(result.get())

运行这个我得到:

<5 seconds wait, time to compute the results>
1
4
9
<5 seconds wait, 3 processes max can run at the same time>
16
25

【讨论】:

  • 您能否告诉 Pool 是每次创建新进程还是仅使用先前“迭代”中的现有进程?我只是想确保在每次使用 handler 后都会释放内存以避免任何类型的“内存不足”问题
  • 它不能使用以前的进程。这是一个进程池。可以添加一个假的大矩阵,看看内存是否爆炸。但无论如何它不会因为垃圾收集器而耗尽内存。
猜你喜欢
  • 2018-05-15
  • 2013-01-16
  • 1970-01-01
  • 2015-02-22
  • 2016-03-18
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多