自动终止多进程池中的进程及其子进程

12 投票
1 回答
8558 浏览
提问于 2025-04-18 00:50

我正在使用多进程模块来进行并行处理。下面的代码片段会在某个位置搜索字符串文件名,并返回找到字符串的文件名。但是在某些情况下,搜索过程需要很长时间,所以我想要终止那些超过300秒的搜索过程。为此,我使用了timeout == 300,如下所示,这样可以终止搜索过程,但并不能终止下面代码生成的子进程。

我尝试了多种方法,但都没有成功 :/

我该如何从池中终止父进程以及它的子进程呢?

import os
from multiprocessing import Pool

def runCmd(cmd):
     lresult = os.popen(cmd).read()
     return lresult

main ():
     p = Pool(4)
     data_paths = [list of paths of store data]
     search_cmds = [ "SearchText.exe %s < %s"%(data_path, filename) for data_path in data_paths ]
     results = [p.apply_async(runCmd, (cmd,), callback = log_result) for cmd in search_cmds]
     try:
        for result in results:
            root.append(result.get(timeout=300))
        #rool holds the result of search process
     except TimeoutError:
        for c in multiprocessing.active_children():
            print '----->',c.pid
            os.kill(c.pid, signal.SIGTERM)
     p.close()
     p.join()

if __name__ == '__main__':
    main()

在进程查看器中的进程树:

cmd.exe
------python.exe
----------------python.exe
--------------------------cmd.exe
---------------------------------SearchText.exe
----------------python.exe
--------------------------cmd.exe
---------------------------------SearchText.exe
----------------python.exe
--------------------------cmd.exe
---------------------------------SearchText.exe
----------------python.exe
--------------------------cmd.exe
---------------------------------SearchText.exe

上面的代码片段并没有终止子进程。

--------------------------cmd.exe
---------------------------------SearchText.exe
--------------------------cmd.exe
---------------------------------SearchText.exe
--------------------------cmd.exe
---------------------------------SearchText.exe
--------------------------cmd.exe
---------------------------------SearchText.exe

这些子搜索进程仍然存在,这些子进程也需要被终止。

请指导一下。

谢谢

1 个回答

11

我用psutil模块解决了我的问题。

我在下面的帖子中找到了这个解决方案:

import psutil, os

def kill_proc_tree(pid, including_parent=True):    
    parent = psutil.Process(pid)
    for child in parent.get_children(recursive=True):
        child.kill()
    if including_parent:
        parent.kill()

me = os.getpid()
kill_proc_tree(me)

https://stackoverflow.com/a/4229404/420557

撰写回答