淘宝客网站设计,营销网站的类型,网络营销与策划,百度商桥怎么接网站小编典典
呵呵#xff0c;我昨天自己在研究这个#xff01;假设您无法更改子程序#xff1a;
在Linux上#xff0c;prctl(PR_SET_PDEATHSIG,...)可能是唯一可靠的选择。#xff08;如果绝对有必要终止子进程#xff0c;那么您可能希望将终止信号设置为SIGKILL而不是SIGTE…小编典典
呵呵我昨天自己在研究这个假设您无法更改子程序
在Linux上prctl(PR_SET_PDEATHSIG,...)可能是唯一可靠的选择。如果绝对有必要终止子进程那么您可能希望将终止信号设置为SIGKILL而不是SIGTERM链接到的代码使用SIGTERM但是子级确实可以选择忽略SIGTERM。在Windows上最可靠的选择是使用Job对象。想法是创建一个“作业”一种用于流程的容器然后将子流程放入作业中并设置魔术选项指出“当没有人握住该作业的“手柄”时然后杀死其中的进程”。默认情况下作业的唯一“句柄”是父进程持有的句柄并且当父进程死掉时操作系统将遍历并关闭其所有句柄然后注意这意味着没有用于工作。因此它会按要求杀死孩子。包含使用该win32api模块执行此操作的示例代码。该代码使用CreateProcess发射子而不是subprocess.Popen。原因是他们需要为生成的子项获取一个“进程句柄”并CreateProcess默认将其返回。如果您愿意使用subprocess.Popen那么这是该答案中代码的未经测试的副本它使用subprocess.Popen和OpenProcess代替CreateProcess
import subprocess
import win32api
import win32con
import win32job
hJob win32job.CreateJobObject(None, )
extended_info win32job.QueryInformationJobObject(hJob, win32job.JobObjectExtendedLimitInformation)
extended_info[BasicLimitInformation][LimitFlags] win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
win32job.SetInformationJobObject(hJob, win32job.JobObjectExtendedLimitInformation, extended_info)
child subprocess.Popen(...)
# Convert process id to process handle:
perms win32con.PROCESS_TERMINATE | win32con.PROCESS_SET_QUOTA
hProcess win32api.OpenProcess(perms, False, child.pid)
win32job.AssignProcessToJobObject(hJob, hProcess)
从技术上讲这里有一个很小的比赛条件以防孩子在Popen和OpenProcess呼叫之间死亡您可以决定是否要担心这一点。
使用作业对象的一个缺点是在Vista或Win7上运行时如果从Windows
Shell启动程序即通过单击图标则可能已经分配了一个作业对象并尝试创建一个作业对象。新的作业对象将失败。Win8可以解决此问题通过允许嵌套作业对象或者如果您的程序是从命令行运行的那么应该可以。
如果您 可以
修改子级例如像使用时一样multiprocessing那么最好的选择可能是以某种方式将父级的PID传递给子级例如作为命令行参数或者在的args参数中multiprocessing.Process然后
在POSIX上在子级中生成一个os.getppid()偶尔会调用的线程如果返回值停止匹配从父级传入的pid则调用os._exit()。这种方法可移植到包括OS
X在内的所有Unix上而prctl窍门是特定于Linux的。
在Windows上在使用OpenProcess和的子代中产生一个线程os.waitpid。使用ctypes的示例
from ctypes import WinDLL, WinError
from ctypes.wintypes import DWORD, BOOL, HANDLE
# Magic value from http://msdn.microsoft.com/en-us/library/ms684880.aspx
SYNCHRONIZE 0x00100000
kernel32 WinDLL(kernel32.dll)
kernel32.OpenProcess.argtypes (DWORD, BOOL, DWORD)
kernel32.OpenProcess.restype HANDLE
parent_handle kernel32.OpenProcess(SYNCHRONIZE, False, parent_pid)
# Block until parent exits
os.waitpid(parent_handle, 0)
os._exit(0)
这避免了我提到的作业对象的任何可能的问题。
如果您想真正确定那么可以组合所有这些解决方案。
希望有帮助
2020-06-02