关于python:杀死正在运行的子进程调用

Kill a running subprocess call

我正在Python上用subprocess启动一个程序。

在某些情况下,程序可能会冻结。 这是我无法控制的。 我从命令行启动的唯一办法是CtrlEsc,它可以快速杀死程序。

有没有办法用subprocess模拟这个? 我正在使用subprocess.Popen(cmd, shell=True)来启动该程序。


好吧,subprocess.Popen()返回的对象有几种方法可能有用:Popen.terminate()Popen.kill(),分别发送SIGTERMSIGKILL

例如...

1
2
3
4
5
6
import subprocess
import time

process = subprocess.Popen(cmd, shell=True)
time.sleep(5)
process.terminate()

...将在五秒钟后终止该过程。

或者您可以使用os.kill()发送其他信号,例如SIGINT来模拟CTRL-C,...

1
2
3
4
5
6
7
8
import subprocess
import time
import os
import signal

process = subprocess.Popen(cmd, shell=True)
time.sleep(5)
os.kill(process.pid, signal.SIGINT)


1
2
p = subprocess.Popen("echo 'foo' && sleep 60 && echo 'bar'", shell=True)
p.kill()

查看subprocess模块上的文档以获取更多信息:http://docs.python.org/2/library/subprocess.html


你的问题不太清楚,但如果我假设你即将启动一个进入僵尸的进程,你希望能够在你的脚本的某些状态下控制它。如果在这种情况下,我建议你以下:

1
p = subprocess.Popen([cmd_list], shell=False)

这并不是真的要求通过shell。
我建议你使用shell = False,这样你就可以减少溢出的风险。

1
2
3
4
5
6
7
8
9
10
11
# Get the process id & try to terminate it gracefuly
pid = p.pid
p.terminate()

# Check if the process has really terminated & force kill if not.
try:
    os.kill(pid, 0)
    p.kill()
    print"Forced kill"
except OSError, e:
    print"Terminated gracefully"


您可以使用两个信号来终止正在运行的子进程调用,即signal.SIGTERM和signal.SIGKILL;例如

1
2
3
4
5
6
7
8
9
10
11
12
13
import subprocess
import os
import signal
import time
..
process = subprocess.Popen(..)
..
# killing all processes in the group
os.killpg(process.pid, signal.SIGTERM)
time.sleep(2)
if process.poll() is None:  # Force kill if process is still alive
    time.sleep(3)
    os.killpg(process.pid, signal.SIGKILL)