Bdfy
Bdfy

Reputation: 24621

how to kill process and child processes from python?

for example from bash:

kill -9 -PID 

os.kill(pid, signal.SIGKILL) kill only parent process.

Upvotes: 41

Views: 83369

Answers (7)

Mikhail_Sam
Mikhail_Sam

Reputation: 11208

None of answers can helped me, so I made some research and wrote my answer: you can easily do it using os module, but it is platform sensitive. This mean that some commands are availiable only on Unix, some - on any platform. So my project starts one Process, and several Child processes in the different places and times. Some of Child starts Grand-Child Processes :) So I found this solution:

import os
import signal
import platform
# get the current PID for safe terminate server if needed:
PID = os.getpid()
if platform.system() != 'Windows':
    PGID = os.getpgid(PID)
if platform.system() != 'Windows':
    os.killpg(PGID, signal.SIGKILL)
else:
    os.kill(PID, signal.SIGTERM)

I use SIGKILL on Linux, to kill process immediatly, and SIGTERM on Windows, because there is no SIGKILL on it. Also I used killpg() to kill the whole group of processes on Linux.

P.S. Check on Linux, but still doesn't check on Windows, so maybe we need one more additional command for Windows (for example CTRL_C_EVENT or use another answer.)

Upvotes: 2

thomas chaton
thomas chaton

Reputation: 1

def kill_children_processes(pid):
    # TODO: Find a way to not have to use a kill -9.
    processes = os.popen("ps -ej | grep -i 'python' | grep -v 'grep' | awk '{ print $2,$3 }'").read()
    processes = [p.split(" ") for p in processes.split("\n")[:-1]]
    processes = "\n".join([child for child, parent in processes if parent == str(pid) and child != str(pid)])
    if processes:
        logger.debug(f"Killing ghost processes {processes}")
        os.system(f"kill -9 {processes}")

Upvotes: -1

jung rhew
jung rhew

Reputation: 870

If the parent process is not a "process group" but you want to kill it with the children, you can use psutil (https://psutil.readthedocs.io/en/latest/#processes). os.killpg cannot identify pid of a non-process-group.

import psutil

parent_pid = 30437   # my example
parent = psutil.Process(parent_pid)
for child in parent.children(recursive=True):  # or parent.children() for recursive=False
    child.kill()
parent.kill()

Upvotes: 60

Hurri
Hurri

Reputation: 11

I don't know if this is what you asked for, but if you wish to kill other processes of your application and they were all created using multiprocessing package you can do something like this:

import multiprocessing
from time import sleep

...

def on_shutdown():
    for child in multiprocessing.active_children():
        print('Terminating', child)
        child.terminate()
        sleep(0.5)

Upvotes: 1

Alan Shi
Alan Shi

Reputation: 103

you should use signal parameter 9 to kill the process tree.

root@localhost:~$ python
>>> import os
>>> os.kill(pid, 9)

if you should use signal.SIGKILL constant, you should use os.killpg(pgid, signal.SIGKILL) to kill the process tree.

Upvotes: 0

ther
ther

Reputation: 888

Another solution if your process is not a process group and you don't want to use psutil, is to run this shell command:

pkill -TERM -P 12345

For instance with

os.system('pkill -TERM -P {pid}'.format(pid=12345))

Upvotes: 6

Thomas Wouters
Thomas Wouters

Reputation: 133395

When you pass a negative PID to kill, it actually sends the signal to the process group by that (absolute) number. You do the equivalent with os.killpg() in Python.

Upvotes: 41

Related Questions