经验证,subprocess自带的kill和terminate函数都不能完全杀掉启动的所有子进程
此时需要借助os的killpg来完成击杀
以判断一个ping命令是否超时,若超时则杀掉进程组为例
要注意的是:
1.这里的subprocess启动的会是一个进程组,有调用ping命令的sh命令,还有ping命令本身,至少会存在两个进程,所以需要将他们都杀掉
解决:通过进程id找到进程组id,os.getpgid(p.id),然后用killpg击杀整个组
2.subprocess的子进程和python脚本处于同一进程组,如果直接通过killpg杀掉整个进程组,会导致整个python脚本被杀掉
解决:另起炉灶,subprocess.Popen中,把start_new_session选项设为True,则subprocess启动的进程不会与python脚本公用同一进程组
借助Timer计时器,用以设置超时时间,以及延时执行kill命令
上代码!
#using os && signal to make sure all subprocess was killed
import os
import signal
#subprocess to run shell command
import subprocess
#using Timer to control command run time, or start time (unit = s)
from threading import Timer
#[def] kill process
def kill_command(p):
os.killpg(os.getpgid(p.pid),signal.SIGTERM)
#[fucdef] kill subprocess when (ping) timeout
#[usedef] disconnect this robot and continue try connect other robots when connect timeout
def execute_command_popen(command,timeout):
# run shell command
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True,start_new_session=True)
# set timer to kill process
timer = Timer(timeout, kill_command,[p])
try:
timer.start()
stdout,stderr = p.communicate()
return_code = p.returncode
print(return_code)
print(stdout)
except Exception as ex:
print(ex)
finally:
timer.cancel()
execute_command_popen('ping xxx.xxx.xxx.xxx -c4', 20)
print("continue!")
return_code返回值:
0,表示执行成功;
负数,代表执行有误或中断;
None,表示进程仍未执行完。
最后打印一个continue!为了观测出python进程是否被整个杀死,我们希望只杀掉所有subprocess进程而保留python进程。
正确的情况下,若规定超时时间内,ping指令已经执行成功,则会打印出0和ping命令产生的log和最后的continue!
,ping指令仍未执行成功,则会打印出负数和空log和最后的continue!
浙公网安备 33010602011771号