2017-06-16 130 views
1

我正在使用python多处理来拆分较长的进程并且并行运行。它工作正常,除非其中一个子进程出现异常,在这种情况下,进程池未关闭,我仍然可以在服务器上看到这些进程。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; 

在给予pool.close里面除了块,它说

NameError: global name 'pool' is not defined

我想杀就用下面的代码异常的过程。

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但他们不是真的这个问题。

+1

您是否在调用'pool.close()'之前尝试使用'r.get()'得到结果?我认为在调用'pool.map()'之后,在你得到结果之前,进程不会退出。哦,你不应该试图触摸子进程中的'pool'对象,正如文档所述:'请注意池的方法只能由创建它的进程使用。' – Maciek

+0

谢谢@Maciek,我通过把整个父进程代码放在try ... except块中得到了解决方案。将其作为下面的答案分享。 – Codeformer

回答

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

而在子进程功能:

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

的拦网除外这里看起来多余的,但事实并非如此。原因是,子进程引发的一些异常没有被抛到父进程中。例如,我在函数中引发了一个自定义的异常,并且它没有抛给父进程,所以建议在子进程中捕获所有的异常并从那里引发标准异常,然后在父进程中处理它,您可以关闭进程池或进行其他清理。