Python窗口在“无关”父进程死亡/崩溃时退出子进程

2024-09-27 22:20:56 发布

您现在位置:Python中文网/ 问答频道 /正文

经过一些研究,对于如何让一个子进程理解父进程在Windows下已经死亡/崩溃/退出,这会使子进程在无人值守的情况下运行,这一点没有明确的答案。有一些建议,如:

总是涉及到一个已知的父母已经开始了孩子。但有些情况下,孩子不知道自己是孩子,因为孩子不是孩子,父母也不想杀死孩子。在

此外,母公司没有控制权。实际案例:

  • 小天鹅在窗户下奔跑
  • Windows Python第一名
  • Python可执行文件通过setuptools入口点设施安装。在

如上所述,要执行的Python是Windows版本。setuptools生成的可执行文件将找到它,并用附带的脚本作为子进程执行。在

因为在Cygwin下运行,以下可能会失败:

  • Ctrl-c将杀死父级(stub setuptools可执行文件)
  • 但是会让子进程继续运行(在进程列表中可以找到python.exe

在这种情况下,如上所述,不可能控制父对象,而子对象不知道它是子对象(因为它也可以作为Python脚本直接执行)


Tags: 对象答案in脚本child可执行文件进程windows
1条回答
网友
1楼 · 发布于 2024-09-27 22:20:56

解决方法如下

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不同(死亡),则在单独的线程中运行。这在Python3.3下工作,其中os.getppid()实际上返回window下父级的PID

它不需要修改父线程,也不需要预先将子线程编码为子线程,因为它会检查线程必须在何处运行或不运行

重构为函数并添加了来自注释的改进

相关问题 更多 >

    热门问题