关闭多处理 Python 时,外部程序为 运行

External programs are running when multiprocessing Python is closed

在 Python (3.5) 中,我通过 multiprocessing.Pool.map + Xshell 连接的子进程启动了 运行 外部可执行文件(用 C++ 编写)。但是,由于网络状况不佳,Xshell 连接中断。

再次连接后,我看到管理 Python 消失了,但 C++ 可执行文件仍然 运行(看起来以正确的方式,Pool 似乎仍在控制它们。)

问题是这是否是一个错误,在这种情况下我该怎么办。我不能 killkill -9 他们。

添加:手动删除所有sublst_file后,所有运行可执行文件(cmd)都消失了。 except sub.SubprocessError as e: 部分似乎还在工作。

我的程序的基本框架概述如下。

import subprocess as sub
import multiprocessing as mp
import itertools as it
import os
import time

def chunks(lst, chunksize=5):
    return it.zip_longest(*[iter(lst)]*chunksize)

class Work():
    def __init__(self, lst):
        self.lst = lst

    def _work(self, sublst):
       retry_times = 6
       for i in range(retry_times):
             try:
                 cmd = 'my external c++ cmd'
                 sublst_file = 'a config file generated from sublst'
                 sub.check_call([cmd, sublst_file])
                 os.remove(sublst_file)
                 return sublst # return success sublst
             except sub.SubprocessError as e:
                 if i == (retry_times-1):
                    print('\n[ERROR] %s %s failed after %d tries\n' % (cmd, sublst_file, retry_times))
                    return []
                 else:
                     print('\n[WARNNING] %dth sleeping, please waiting for restart\n' % (i+1))
                     time.sleep(1+i)

    def work(self):
        with mp.Pool(4) as pool:
            results = pool.map(self._work, chunks(self.lst, 5))
        for r in it.chain(results):
            # other work on success items
            print(r)

multiprocessing.Pool 确实会在 terminate() 时终止其工作程序,__del__ 也会调用它,后者又会在模块卸载时(退出时)调用。

这些家伙成为孤儿的原因是 subprocess.check_call 生成在退出时没有终止。

参考文献中没有明确提及这一事实,但没有任何迹象表明生成已终止。对 source code 的简要回顾也没有给我留下任何发现。这种行为也很容易测试。

要在父进程终止时进行清理,请使用 Popen 界面和此答案 Killing child process when parent crashes in python