根据SDK,有一些Win32对象可以“继承”给定进程创建的子进程。 (事件,互斥,管道......)
这究竟意味着什么?
假设我有一个命名的事件对象,使用CreateEvent
创建,一次使用bInheritHandle == true
,另一次使用== false
。
现在我开始一个子进程。这两个事件句柄如何影响子进程?它们在哪些情况下有所不同?
答案 0 :(得分:14)
如果您创建/打开一个对象并允许继承该句柄,则允许继承句柄的子进程(例如,您可以为CreateProcess指定bInheritHandles = TRUE
)将具有这些句柄的副本。这些继承的句柄将具有与父句柄相同的句柄值。例如:
CreateEvent
返回事件对象的句柄,句柄为0x1234
。0x1234
,而无需致电CreateEvent
或OpenEvent
。例如,您可以在子进程的命令行中传递句柄值。这对于未命名的对象很有用 - 因为它们未命名,其他进程无法打开它们。使用句柄继承子进程可以获取未命名对象的句柄(如果需要)。
答案 1 :(得分:2)
现有答案中尚未提出的一点是,允许子进程继承句柄并不会影响子进程;它也可能影响句柄引用的对象的生命周期。如果父进程退出,子进程中的句柄将使对象保持活动状态。
当允许子进程继承句柄时,您必须考虑它是否会导致对象的生存时间超过它应该;例如,某些应用程序只希望允许一次运行一个实例,并且可以通过创建具有给定名称的事件对象并查看它是否已存在来实现。如果他们创建一个继承该事件对象的子进程,并且比父进程寿命长,则可能导致误报。
更常见的情况是,文件的继承句柄可能导致文件仍在使用(因此无法访问)的时间超过应有的时间。
出于这个原因,最佳做法是:
将所有句柄设为不可继承,除非特别需要继承。
如果子流程不需要继承句柄,请为FALSE
传递bInheritHandles
。
如果子进程确实需要继承句柄,only allow it to inherit those specific handles that are needed。
另一方面,这偶尔会有用;例如,如果您希望将子进程计为父进程的实例,或者在子进程退出之前使文件仍然无法访问。另一个技巧是让子进程继承命名对象的句柄,然后使用对象的存在或不存在来确定子进程是否仍然存活,而不必传递进程句柄或进程ID。
答案 2 :(得分:1)
如果您创建了一个事件,并允许子进程继承该句柄,那么子进程可以使用句柄来完成父进程创建的完全相同的对象。这可以在子任务完成任务时使用事件句柄向父级发信号的方式使用(对于可继承的事件对象句柄有许多其他用途)。
编辑: 删除了虚假信息。