0%

Python-杀死subprocess进程

Pre:

在整合第三方工具的时候,我们常常会用subprocess库来调用可执行文件.

一般情况下,我们会等待这个命令的结束.

但有时候第三方工具会因为特殊情况而卡死,从而导致整个程序卡死.

此时,我们可以设置一个最大的超时时间.

当这个命令超过这个最大时间的时候,我们主动kill掉,以保证程序接下来可以正常运行.


py3:

1
2
3
4
5
6
7
8
9
p = subprocess.Popen([cmd],stdout=subprocess.PIPE)

try:
(stdoutput, erroutput) = p.communicate(timeout=TIMEOUT) # 超时时间
except subprocess.TimeoutExpired:
p.kill()
print("[*] TIMEOUT: %s" % cmd)
except Exception as e:
pass

py3的subprocess库原生支持了超时时间的参数.

过了超时时间的时候,会抛出TimeoutExpired异常.我们只需要catch到再做处理就行了.


py2:

没想到py2的subprocess库还并没有支持timeout参数.只能自己手动计时.到时间kill掉.

搜索到的实现比较好的示例代码,只需要简单改改就可以用了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import subprocess

from threading import Timer

kill = lambda process: process.kill()
cmd = ['ping', 'www.google.com']
ping = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

my_timer = Timer(5, kill, [ping])

try:
my_timer.start()
stdout, stderr = ping.communicate()
finally:
my_timer.cancel()

另一种卡死的情况:

原因是使用Popen.wait()后直接读PIPE.stdout.read()之前,可能缓存已经满了,此时导致了卡死。

解决办法:使用communicate(),这个方法会把输出放在内存,而不是管道里,所以这时候上限就和内存大小有关了,一般不会有问题。


refs: