Joblib Parallel 不会终止进程

Ива*_*дос 10 python memory-leaks multiprocessing joblib

我按以下方式并行运行代码:

grouped_data = Parallel(n_jobs=14)(delayed(function)(group) for group in grouped_data)
Run Code Online (Sandbox Code Playgroud)

计算完成后,我可以在系统监视器中看到所有生成的进程仍然处于活动状态并且消耗内存:

在此输入图像描述

并且所有这些进程都不会被杀死,直到主进程终止,这会导致内存泄漏。如果我按以下方式对 multiprocessing.Pool 执行相同操作:

pool = Pool(14)
pool.map(apply_wrapper, np.array_split(groups, 14))
pool.close()
pool.join()
Run Code Online (Sandbox Code Playgroud)

然后我看到所有生成的处理最终都终止并且没有内存泄漏。但是,我需要 joblib 并且它是不稳定的后端,因为它允许序列化一些本地函数。

如何强制终止 joblib.Parallel 生成的进程并释放内存?我的环境如下:Python 3.8,Ubuntu Linux。

Ива*_*дос 11

我自己调查后可以总结一下:

  1. joblib.Parallel 没有义务在成功单次调用后终止进程
  2. Loky 后端不会以物理方式终止工人,这是作者解释的有意设计:Loky Code Line
  3. 如果您想明确释放工作人员,您可以使用我的代码片段:
    import psutil
    current_process = psutil.Process()
    subproc_before = set([p.pid for p in current_process.children(recursive=True)])
    grouped_data = Parallel(n_jobs=14)(delayed(function)(group) for group in grouped_data)
    subproc_after = set([p.pid for p in current_process.children(recursive=True)])
    for subproc in subproc_after - subproc_before:
        print('Killing process with pid {}'.format(subproc))
        psutil.Process(subproc).terminate()
Run Code Online (Sandbox Code Playgroud)
  1. 上面的代码不是线程/进程保存的。如果您有另一个产生子进程的来源,您应该阻止它的执行。
  2. 一切都适用于 joblib 版本 1.0.1