首页 > 解决方案 > 如何杀死由 subprocess.Popen() 进程产生的子进程?

问题描述

subprocess.Popen用来产生一个新的子进程 - 在这种情况下git clone

问题是它git clone本身会产生子进程,当我尝试Popen.kill()仅使用父进程 ( git clone) 杀死它们时,它会被杀死,而不是它的子进程。

一个孩子的例子是:

79191 /usr/lib/git-core/git fetch-pack --stateless-rpc --stdin --lock-pack --include-tag --thin --cloning --depth=1 https://example.com/scm/adoha/adoha_digit_interpretation.git/

我怎样才能杀死所有的进程 -git clone及其子进程?

注意:我考虑过将这些进程放在他们自己的进程组中,但随后主进程也被杀死了。

    # execute a child process using os.execvp()
    p = subprocess.Popen(shlex.split(f'git clone --bare --depth=1 -v \'{url}\' \'{temp_dir}\''),
                         stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    try:
        ret_code = p.wait(timeout)
    except subprocess.TimeoutExpired as exc:
        p.kill()
        shutil.rmtree(temp_dir)
        raise common.exc.WatchdogException(f'Failed to clone repository: Timeout.'
                                           f'\n{timeout=}\n{url=}') from exc

标签: pythonpython-3.x

解决方案


您可以使用以下代码段终止进程及其子进程:

import psutil


def kill_process_and_children(pid: int, sig: int = 15):
    try:
        proc = psutil.Process(pid)
    except psutil.NoSuchProcess as e:
        # Maybe log something here
        return

    for child_process in proc.children(recursive=True):
        child_process.send_signal(sig)

    proc.send_signal(sig)

kill_process_and_children(p.pid)

推荐阅读