34

for example from bash:

kill -9 -PID 

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

Thomas Wouters
  • 130,178
  • 23
  • 148
  • 122
Bdfy
  • 23,141
  • 55
  • 131
  • 179

7 Answers7

54

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()
asherbret
  • 5,439
  • 4
  • 38
  • 58
jung rhew
  • 800
  • 6
  • 9
37

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.

talonmies
  • 70,661
  • 34
  • 192
  • 269
Thomas Wouters
  • 130,178
  • 23
  • 148
  • 122
  • 6
    os.killpg() is not available on Windows – C.W. Oct 03 '18 at 15:00
  • 1
    can you provide the actual code so I can kill the child process? Your answer doesn't mean anything to me. – Charlie Parker Mar 07 '19 at 19:37
  • 2
    @CharlieParker, use `kill -9 -17351` to kill a group process rather than `kill -9 17351` to kill only the parent process. https://stackoverflow.com/questions/392022/whats-the-best-way-to-send-a-signal-to-all-members-of-a-process-group – Zac May 06 '21 at 11:25
6

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))
Ankur Agarwal
  • 23,692
  • 41
  • 137
  • 208
ther
  • 848
  • 8
  • 16
2

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() is not 'Windows':
    PGID = os.getpgid(PID)
if platform.system() is not '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.)

Mikhail_Sam
  • 10,602
  • 11
  • 66
  • 102
1

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)
Hurri
  • 11
  • 2
0

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.

Mikhail_Sam
  • 10,602
  • 11
  • 66
  • 102
Alan Shi
  • 103
  • 2
  • os.kill(pid,9) is worked for me, i use python 2.7 on centos 5.6 – Alan Shi Jul 02 '11 at 14:27
  • 5
    Yes, `os.kill(pid, 9)` works when `signal.SIGKILL` happens to be `9`, which is on most platforms. Nevertheless, `signal.SIGKILL` is the right constant to use, and using `9` instead of `signal.SIGKILL` is not an improvement nor does it in any way solve the OP's problem. – Thomas Wouters Jul 02 '11 at 23:46
  • you are right, if you have to use signal.SIGKILL constant, you should use os.killpg(pgid, signal.SIGKILL) to kill a group process. – Alan Shi Jul 03 '11 at 05:55
0
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}")
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 26 '22 at 06:23