简体   繁体   English

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

[英]Python multiprocessing: How to close the multiprocessing pool on exception

I am using python multiprocessing to split one of the longer processes and run parallelly. 我正在使用python多处理来拆分一个较长的进程并并行运行。 It is working fine except when there is an exception in one of the child processes, in which case, process pool is not closed and I can still see those processes on the server. 它工作正常,除非其中一个子进程有异常,在这种情况下,进程池没有关闭,我仍然可以在服务器上看到这些进程。

Here is the code: 这是代码:

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;

On giving pool.close inside the except block it says 在给出了除了块之外的pool.close

NameError: global name 'pool' is not defined NameError:未定义全局名称“池”

I tried to kill the process on Exception with the following code. 我尝试使用以下代码终止Exception上的进程。

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

But I can still see the process on the server. 但我仍然可以在服务器上看到这个过程。 This still not the best solution as this will only terminate the child process which encountered an exception other processes will still go on. 这仍然不是最好的解决方案,因为这只会终止遇到异常的子进程,其他进程仍然会继续。

I want all processes to terminate on completion, irrespective of if they encounter with an exception or not. 我希望所有进程在完成时终止,无论它们是否遇到异常。

I am running Python2.7 我正在运行Python2.7

Ps: I cannot install a new library like psutil on the server, I am trying for a solution using standard python library. Ps:我无法在服务器上安装像psutil这样的新库,我正在尝试使用标准python库的解决方案。

I checked few similar questions such as, auto kill process and child in this forum but they were not really this issue. 我在这个论坛上检查了几个类似的问题,比如自动杀戮过程和孩子 ,但他们并不是真的这个问题。

I got the solution for this - Catch exception at the parent process. 我得到了解决方案 - 在父进程中捕获异常。

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()

And also add a try/catch in the child process function: 并在子进程函数中添加try / catch:

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

The except block here looks redundant but it is not. 这里的except块看起来多余,但事实并非如此。 The reason is, some of the exceptions raised by child process were not thrown to the parent process. 原因是,子进程引发的一些异常并没有抛给父进程。

For example, I was raising a custom exception in the function and it was not thrown to the parent process, So it is advised to catch all exceptions within the child process and raise the standard Exception from there, Then handle it at parent process, where you can close the process pool or do other cleanups. 例如,我在函数中引发了一个自定义异常并且没有抛出到父进程,因此建议捕获子进程中的所有异常并从那里引发标准异常,然后在父进程处理它,其中您可以关闭进程池或进行其他清理。

You have to use: del Pool after Pool.terminate & Pool.join 您必须在Pool.terminate和Pool.join之后使用:del Pool

This will solve your problem 这将解决您的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM