Python多处理:如何在异常时关闭多处理池

Posted

技术标签:

【中文标题】Python多处理:如何在异常时关闭多处理池【英文标题】:Python multiprocessing: How to close the multiprocessing pool on exception 【发布时间】:2017-11-19 03:18:40 【问题描述】:

我正在使用 python 多处理来拆分较长的进程之一并并行运行。它工作正常,除非其中一个子进程出现异常,在这种情况下,进程池没有关闭,我仍然可以在服务器上看到这些进程。

代码如下:

from multiprocessing import Pool
pool = Pool(processes=4)
from functools import partial
param_data = "Test Value"
func = partial(test_function, param_data)
r = pool.map(func, range(3))
pool.close()

def test_function(param_data,index):
   try:
      # The process here;
   except Exception as e:
      # Close the process pool;

在它说的 except 块内提供pool.close

NameError:未定义全局名称“池”

我尝试使用以下代码终止异常进程。

    except Exception as e:
       import os
       import signal
       pid = os.getpid()
       os.kill(pid, signal.SIGTERM) 

但我仍然可以看到服务器上的进程。这仍然不是最好的解决方案,因为这只会终止遇到异常的子进程,其他进程仍会继续。

我希望所有进程在完成时终止,无论它们是否遇到异常。

我正在运行 Python2.7

Ps:我无法在服务器上安装像 psutil 这样的新库,我正在尝试使用标准 python 库的解决方案。

我在这个论坛上查了几个类似的问题,例如auto kill process and child,但它们并不是真正的问题。

【问题讨论】:

在调用pool.close() 之前,您是否尝试使用r.get() 获取结果?我认为在调用pool.map() 后,在您获得结果之前,这些进程不会退出。哦,您不应该尝试从子进程中触摸 pool 对象,如文档所述:Note that the methods of a pool should only ever be used by the process which created it. 谢谢@Maciek,我通过将整个父进程代码放在 try ... except 块中得到了解决方案。在下面分享它作为答案。 【参考方案1】:

我得到了解决方案 - 在父进程中捕获异常。

try:
   pool = Pool(processes=4)
   from functools import partial
   param_data = "Test Value"
   func = partial(test_function, param_data)
   r = pool.map(func, range(3))
except Exception as e:
   pool.close()
pool.close()

并且还在子进程函数中添加一个try/catch:

def test_function(param_data,index):
    try:
       # The process here;
    except Exception as e:
       raise Exception(e.message)          

这里的 except 块看起来是多余的,但事实并非如此。 原因是,子进程引发的一些异常没有被抛出到父进程。

例如,我在函数中引发了一个自定义异常并且它没有被抛出到父进程,因此建议捕获子进程中的所有异常并从那里引发标准异常,然后在父进程中处理它进程,您可以在其中关闭进程池或进行其他清理。

【讨论】:

我认为pool.close() 还不足以释放资源。之后你应该打电话给pool.terminate()【参考方案2】:

你必须使用: 德尔池 后 Pool.terminate & Pool.join

这会解决你的问题

【讨论】:

以上是关于Python多处理:如何在异常时关闭多处理池的主要内容,如果未能解决你的问题,请参考以下文章

如何在python 2.7中使用pymongo进行多处理池

Python:使用多处理池时使用队列写入单个文件

如何初始化具有共享状态的python多处理工作者池?

如何使Python多处理池工作以写入相同的日志文件

python多进程-进程池模式退出异常解决办法

Python多处理池在加入时挂起?