栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Python:当父母去世时,如何杀死子进程?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python:当父母去世时,如何杀死子进程?

呵呵,昨天我只是在自己研究!假设您无法更改子程序:

在Linux上,

prctl(PR_SET_PDEATHSIG,...)
可能是唯一可靠的选择。(如果绝对有必要终止子进程,那么您可能希望将死亡信号设置为SIGKILL而不是SIGTERM;链接到的代码使用SIGTERM,但是子级确实可以选择忽略SIGTERM。

在Windows上,最可靠的选择是使用Job对象。这个想法是,您创建一个“
Job”(一种用于流程的容器),然后将子流程放入Job中,并设置了一个神奇的选项,说“当没有人握住该Job的“手柄”时,然后杀死其中的进程”。默认情况下,作业的唯一“句柄”是父进程持有的句柄,并且当父进程死亡时,操作系统将遍历并关闭其所有句柄,然后注意这意味着没有用于工作。因此,它会按要求杀死孩子。(如果您有多个子进程,则可以将它们全部分配给同一作业。)此答案包含使用

win32api
模块执行此操作的示例代码。该代码使用
CreateProcess
发射孩子,而不是
subprocess.Popen
。原因是他们需要为生成的子项获取一个“进程句柄”,并
CreateProcess
默认将其返回。如果您愿意使用
subprocess.Popen
,那么这是该答案中代码的(未经测试的)副本,它使用
subprocess.Popen
OpenProcess
代替
CreateProcess

import subprocessimport win32apiimport win32conimport win32jobhJob = win32job.CreateJobObject(None, "")extended_info = win32job.QueryInformationJobObject(hJob, win32job.JobObjectExtendedLimitInformation)extended_info['BasicLimitInformation']['LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSEwin32job.SetInformationJobObject(hJob, win32job.JobObjectExtendedLimitInformation, extended_info)child = subprocess.Popen(...)# Convert process id to process handle:perms = win32con.PROCESS_TERMINATE | win32con.PROCESS_SET_QUOTAhProcess = 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, WinErrorfrom ctypes.wintypes import DWORD, BOOL, HANDLE# Magic value from http://msdn.microsoft.com/en-us/library/ms684880.aspxSYNCHRonIZE = 0x00100000kernel32 = WinDLL("kernel32.dll")kernel32.OpenProcess.argtypes = (DWORD, BOOL, DWORD)kernel32.OpenProcess.restype = HANDLEparent_handle = kernel32.OpenProcess(SYNCHRONIZE, False, parent_pid)# Block until parent exitsos.waitpid(parent_handle, 0)os._exit(0)

这避免了我提到的作业对象的任何可能的问题。

如果您想真正确定,那么可以组合所有这些解决方案。

希望有帮助!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/626280.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号