Skip to content

Instantly share code, notes, and snippets.

@jizhilong
Created September 24, 2013 16:37
Show Gist options
  • Save jizhilong/6687481 to your computer and use it in GitHub Desktop.
Save jizhilong/6687481 to your computer and use it in GitHub Desktop.
how to kill a process's child processes in python
#!/usr/bin/env python
import multiprocessing
import time
import subprocess, os, signal, sys
def test(s):
while True:
print s
time.sleep(1.5)
def kill_child_processes(signum, frame):
parent_id = os.getpid()
ps_command = subprocess.Popen("ps -o pid --ppid %d --noheaders" % parent_id, shell=True, stdout=subprocess.PIPE)
ps_output = ps_command.stdout.read()
retcode = ps_command.wait()
for pid_str in ps_output.strip().split("\n")[:-1]:
os.kill(int(pid_str), signal.SIGTERM)
sys.exit()
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=4)
result = pool.map_async(test, 'abcd')
signal.signal(signal.SIGTERM, kill_child_processes)
result.get(10000)
pool.close()
pool.join()
@brando90
Copy link

brando90 commented Mar 7, 2019

I don't get it, why is the code for something so conceptually simple so complicated?

@pcattori
Copy link

pcattori commented Oct 16, 2019

@brando90 you can use psutil and the following code to create a self-cleaning process:

from contextlib import contextmanager
import subprocess

import psutil


@contextmanager
def process(*args, **kwargs):
    proc = subprocess.Popen(*args, **kwargs)
    try:
        yield proc
    finally:
        for child in psutil.Process(proc.pid).children(recursive=True):
            child.kill()
        proc.kill()

Note that the *args, **kwargs means that process has the same API as subprocess.Popen 😄

Then you can do:

with process(['mycommand', 'myarg', '--myoption', 'myoptionvalue'], stdout=open('myfile.out.log', 'w')) as proc:
    print(proc.pid)
    0/0 # even though this throws an exception, the `process` contextmanager will *still* clean up the process correctly

@jizhilong
Copy link
Author

@pcattori impressive usage of contextmanager and psutil👍

@yogurfrul
Copy link

os.killpg(os.getpid(), signal.SIGTERM)

@fccoelho
Copy link

os.killpg(os.getpid(), signal.SIGTERM)

Best Solution! thanks!

@amotl
Copy link

amotl commented Dec 5, 2023

@pcattori impressive usage of contextmanager and psutil 👍

I second that, thank you very much for sharing this, Pedro. We just added your code snippet to a little package we are currently gardening, to make it reusable by others, see pyveci/pueblo#39. We hope you don't have any objections about it. It was the last addition amongst a few updates happening last month, so it just become part of pueblo-0.0.4, also available on PyPI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment