经过一些研究,没有明确的答案,如何让子进程了解父进程已经在Windows下死亡/崩溃/退出,这可能使子进程无人值守。有一些建议如下:
始终涉及已经开始生孩子的已知父母。但有些情况下,孩子并不知道这是一个孩子,因为它不是一个孩子,父母也没有努力杀死孩子。
此外,没有父母的控制权。实际案例:
setuptools
entry_points 工具安装的Python可执行文件。如上所述,要执行的Python是Windows。 setuptools生成的可执行文件将找到它并使用asocciated脚本作为子进程执行它。
因为一个人在Cygwin下运行,所以可能会失败:
Ctrl-c
将终止父(存根setuptools可执行文件)python.exe
)在这种情况下,如上所述,不可能控制父母,孩子也不会知道孩子(因为它也可能直接作为Python脚本执行)
答案 0 :(得分:1)
解决方案如下:
import sys
def win_wait_for_parent(raise_exceptions=False):
if not sys.platform == 'win32':
return True
# When started under cygwin, the parent process will die leaving a child
# hanging around. The process has to be waited upon
import ctypes
from ctypes.wintypes import DWORD, BOOL, HANDLE
import os
import threading
INFINITE = -1
SYNCHRONIZE = 0x00100000
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
kernel32.OpenProcess.argtypes = (DWORD, BOOL, DWORD)
kernel32.OpenProcess.restype = HANDLE
kernel32.WaitForSingleObject.argtypes = (HANDLE, DWORD)
kernel32.WaitForSingleObject.restype = DWORD
phandle = kernel32.OpenProcess(SYNCHRONIZE, 0, os.getppid())
def check_parent():
# Get a token with right access to parent and wait for it to be
# signaled (die). Exit ourselves then
kernel32.WaitForSingleObject(phandle, INFINITE)
os._exit(0)
if not phandle:
if raise_exceptions:
raise ctypes.WinError(ctypes.get_last_error())
return False
threading.Thread(target=check_parent).start()
return True
如果进程的PID与等待父级的父级的PID(死亡)不同,则在单独的线程中运行。这适用于Python 3.3,其中os.getppid()
确实在窗口
它不需要修改父项,并且孩子不需要事先作为孩子进行编码,因为检查了线程必须运行的位置或者没有。
- 重构为函数并添加了注释的改进