我在Windows XP SP3上使用Python 2.6.6和pywin32-218。
我的Python应用程序有第二个线程(除了主线程之外),该线程生成一个子进程来运行另一个Windows可执行文件。
我的问题是,当主进程(python.exe)被终止(例如使用taskkill命令时),我想终止子进程(calc.exe)并执行一些清理工作。
我尝试了各种方法(atexit、signal和win32api.handleConsoleCtrl),但似乎都无法捕获taskkill信号。
以下是我的代码(test.py):
import sys
import os
import signal
import win32api
import atexit
import time
import threading
import subprocess
class SecondThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.secondProcess = None
def run(self):
secondCommand = ['C:\WINDOWS\system32\calc.exe']
self.secondProcess = subprocess.Popen(secondCommand)
print 'calc.exe running'
self.secondProcess.wait()
print 'calc.exe stopped'
# do cleanup here
def stop(self):
if self.secondProcess and self.secondProcess.returncode == None:
self.secondProcess.kill()
secondThread = SecondThread()
def main():
secondThread.start()
def cleanup():
print 'cleaning up'
secondThread.stop()
print 'cleaned up'
atexit.register(cleanup)
def handleSignal(signalNum, frame):
print 'handleSignal'
cleanup()
sys.exit(0)
for signalNum in (signal.SIGINT, signal.SIGILL, signal.SIGABRT, signal.SIGFPE, signal.SIGSEGV, signal.SIGTERM):
signal.signal(signalNum, handleSignal)
def handleConsoleCtrl(signalNum):
print ('handleConsoleCtrl')
cleanup()
win32api.SetConsoleCtrlHandler(handleConsoleCtrl, True)
main()
应用程序启动使用
python.exe test.py
控制台随后会打印“calc.exe正在运行”,计算器应用程序运行,并且使用进程资源管理器,我可以看到calc.exe作为python.exe的子进程。然后我使用以下命令杀死主进程:
taskkill /pid XXXX /f
(其中XXXX是python.exe的PID)之后,命令提示符返回而没有进一步输出(即“cleaning up”,“handleSignal”或“handleConsoleCtrl”都没有打印),计算器应用程序继续运行,并且从Process Explorer中可以看出,python.exe不再运行,但calc.exe已经重新成为了父级进程。