Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-Windows-退出子进程时;无关的;母公司死亡/崩溃_Python_Windows_Python 3.x_Subprocess - Fatal编程技术网

Python-Windows-退出子进程时;无关的;母公司死亡/崩溃

Python-Windows-退出子进程时;无关的;母公司死亡/崩溃,python,windows,python-3.x,subprocess,Python,Windows,Python 3.x,Subprocess,在一些研究之后,对于如何让子进程理解父进程已在Windows下死亡/崩溃/退出,从而使子进程在无人参与的情况下运行,还没有明确的答案。以下是一些建议: 工作: Psutil: 多处理: 总是涉及一个已经生了孩子的已知父母。但在有些情况下,孩子并不知道自己是孩子,因为孩子不是作为孩子被怀上的,父母也不想杀死孩子 此外,不存在对父级的控制。实际案例: 在Windows下运行的Cygwin Windows Python在路径中排名第一 通过setuptoolsentry\u points工具安装

在一些研究之后,对于如何让子进程理解父进程已在Windows下死亡/崩溃/退出,从而使子进程在无人参与的情况下运行,还没有明确的答案。以下是一些建议:

  • 工作:

  • Psutil:

  • 多处理:

总是涉及一个已经生了孩子的已知父母。但在有些情况下,孩子并不知道自己是孩子,因为孩子不是作为孩子被怀上的,父母也不想杀死孩子

此外,不存在对父级的控制。实际案例:

  • 在Windows下运行的Cygwin
  • Windows Python在路径中排名第一
  • 通过
    setuptools
    entry\u points工具安装Python可执行文件
如上所述,要执行的Python是Windows Python。setuptools生成的可执行文件将找到它,并将其作为子流程使用一个意外脚本执行

由于其中一个正在Cygwin下运行,因此以下操作可能会失败:

  • 按Ctrl-c将终止父级(存根setuptools可执行文件)
  • 但将使子进程保持运行(在进程列表中可以找到
    python.exe

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

解决方案如下

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()
实际上返回窗口下父对象的PID

它不需要修改父线程,也不需要将子线程预先编码为子线程,因为会检查线程必须运行的位置或否


--作为一个函数进行重构,并根据注释添加了改进

setuptools EXE包装器有缺陷且过时。只要有可能,构建/安装一个控制盘包,pip使用distlib中的EXE存根来安装它。这些启动器使用一个作业对象来确保子进程与父进程一起终止。
pip install-e。
如果不是在次线程中获取父进程的句柄,并且所有内容都包装在函数中,则引发异常才有意义,imho。这一切都是有道理的,但代码只是一个片段。