简体   繁体   English

如何从 python 杀死进程和子进程?

[英]how to kill process and child processes from python?

for example from bash:例如来自 bash:

kill -9 -PID 

os.kill(pid, signal.SIGKILL) kill only parent process. os.kill(pid, signal.SIGKILL)只杀死父进程。

If the parent process is not a "process group" but you want to kill it with the children, you can use psutil ( https://pythonhosted.org/psutil/#processes ).如果父进程不是“进程组”但您想与子进程一起杀死它,则可以使用 psutil ( https://pythonhosted.org/psutil/#processes )。 os.killpg cannot identify pid of a non-process-group. os.killpg 无法识别非进程组的 pid。

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()

When you pass a negative PID to kill , it actually sends the signal to the process group by that (absolute) number.当您将PID 传递给kill时,它实际上通过该(绝对)数字将信号发送到进程 You do the equivalent with os.killpg() in Python.您可以在 Python 中使用os.killpg()进行等效操作。

Another solution if your process is not a process group and you don't want to use psutil , is to run this shell command:如果您的进程不是进程组并且您不想使用 psutil ,另一种解决方案是运行此 shell 命令:

pkill -TERM -P 12345

For instance with例如与

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

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.没有一个答案可以帮助我,所以我做了一些研究并写下了我的答案:你可以使用os模块轻松地做到这一点,但它是平台敏感的。 This mean that some commands are availiable only on Unix, some - on any platform.这意味着某些命令仅在 Unix 上可用,有些在任何平台上可用。 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:一些 Child 启动 Grand-Child Processes :) 所以我找到了这个解决方案:

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.我在 Linux 上使用SIGKILL来立即终止进程,并在 Windows 上使用SIGTERM ,因为上面没有SIGKILL Also I used killpg() to kill the whole group of processes on Linux.我还使用killpg()杀死 Linux 上的整个进程组。

PS 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 .) PS 检查 Linux,但仍然不检查 Windows,所以也许我们需要对 Windows 再添加一个命令(例如 CTRL_C_EVENT)或使用另一个答案

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:我不知道这是否是您要求的,但是如果您想杀死应用程序的其他进程并且它们都是使用多处理 package 创建的,您可以执行以下操作:

import multiprocessing
from time import sleep

...

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

you should use signal parameter 9 to kill the process tree.您应该使用信号参数 9 来终止进程树。

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.如果你应该使用 signal.SIGKILL signal.SIGKILL constant ,你应该使用os.killpg(pgid, signal.SIGKILL)来杀死进程树。

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}")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM