在 Windows 上优雅地终止子 Python 进程,以便运行 finally 子句 [英] Gracefully Terminate Child Python Process On Windows so Finally clauses run
问题描述
在 Windows 机器上,我有许多场景,其中父进程将启动子进程.出于各种原因 - 父进程可能想要中止子进程,但是(这很重要)允许它清理 - 即运行 finally 子句:
On Windows boxes, I have a number of scenarios where a parent process will start a child process. For various reasons - the parent process may want to abort the child process but (and this is important) allow it to clean up - ie run a finally clause:
try:
res = bookResource()
doStuff(res)
finally:
cleanupResource(res)
(这些东西可能嵌入在更接近的上下文中 - 通常围绕硬件锁定/数据库状态)
(These things may be embedded in contexts like the closer - and generally are around hardware locking/database state)
问题是我无法找到在 Windows 中向孩子发出信号的方法(就像在 Linux 环境中一样),因此它会在终止之前运行清理.我认为这需要让子进程以某种方式引发异常(就像 Ctrl-C 那样).
The problem is that I'm unable to find a way to signal the child in Windows (as I would in a Linux environment) so it would run the clean up before terminating. I think this requires making the child process raise an exception somehow (as the Ctrl-C would).
我尝试过的事情:
- os.kill
- 操作系统信号
subprocess.Popen
与 creationFlags 并使用ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, p.pid)
abrt 信号.这需要一个信号陷阱和不优雅的循环来阻止它立即中止.ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, p.pid)
- ctrl-c 事件 - 什么也没做.
- os.kill
- os.signal
subprocess.Popen
with creationFlags and usingctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, p.pid)
abrt signal. This requires a signal trap and inelegant loop to stop it immediately aborting.ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, p.pid)
- ctrl-c event - did nothing.
有没有人有办法做到这一点,以便子进程可以清理?
Has anyone got a surefire way of doing this, so that the child process can clean up?
推荐答案
我能够让 GenerateConsoleCtrlEvent 像这样工作:
I was able to get the GenerateConsoleCtrlEvent working like this:
import time
import win32api
import win32con
from multiprocessing import Process
def foo():
try:
while True:
print("Child process still working...")
time.sleep(1)
except KeyboardInterrupt:
print "Child process: caught ctrl-c"
if __name__ == "__main__":
p = Process(target=foo)
p.start()
time.sleep(2)
print "sending ctrl c..."
try:
win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT, 0)
while p.is_alive():
print("Child process is still alive.")
time.sleep(1)
except KeyboardInterrupt:
print "Main process: caught ctrl-c"
输出
Child process still working...
Child process still working...
sending ctrl c...
Child process is still alive.
Child process: caught ctrl-c
Main process: caught ctrl-c
这篇关于在 Windows 上优雅地终止子 Python 进程,以便运行 finally 子句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!