最近遇到一個問題,就是在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命令殺進程的時候,還會提示找不到這個進程。