最近遇到一个问题,就是在Windows下怎么杀掉全部的子线程,现把解决方法记录下。
问题来源:
用python执行了一个bat脚本,脚本的内容是执行一系列的adb命令,然后运行一个server。其中需要在新的cmd窗口中运行这些命令,因为最后会在这个窗口中启动一个server,
这个server会一直在运行。因为使用的是thrift架构,在运行测试脚本之前,必须先先启动这个server。现在的问题是,等到测试用例执行完毕之后,这个server还是在运行的,现在就是
想把这个server在用例执行完之后关掉,但是关不掉。原因如下:
a)最开始是使用了os.system()来执行bat脚本,这个方法没有拿到PID
b)然后使pro = subprocess.Popen(cmd.split(), shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)来新起一个线程,这样虽然拿到了PID,这样有个问题,就是
它的本质是另外开启一个cmd命令来运行 adb命令,接下来及时使用popen.terminate()也只能关闭父进程,adb的进程会有系统来托管,这样是不能杀死adb进程的。然后上网查了一个,发现有
subprocess有一个参数是 creationflags=subprocess.CREATE_NEW_PROCESS_GROUP官方解释如下:
A Popen creationflags parameter to specify that a new process group will be created. This flag is necessary for using os.kill() on the subprocess
但是这样还是不能解决问题,因为在运行kill()或者terminate()之后,启动server的那个cmd窗口并没有被关闭。
解决方法:
最后实在没有办法,就用例一个很笨的方法,在程序运行之前,先获取当前电脑上运行的进程有哪些,在程序运行之后,再获取电脑上有哪些进程,前后对比一下,新增加的进程就是原来启动的进程,今夏这些新增加的进程的PID,
当测试用例结束的时候杀掉这些进程。
还有一个问题很迷惑,就是使用subprocess启动的进程,其进程ID在windows的任务管理器里面查不到,使用taskkill命令杀进程的时候,还会提示找不到这个进程。