这是什么意思:"子进程可以继承句柄"?

Dan*_*ski 10 windows winapi handle

根据SDK,有一些Win32对象可以"继承"给定进程创建的子进程.(事件,互斥体,管道......)

这究竟意味着什么?

比方说,我有一个名为事件对象,以创建CreateEvent,一个时间bInheritHandle == true,和其他时间== false.

现在我开始一个子进程.这两个事件句柄如何影响子进程?它们在哪些情况下有所不同?

wj3*_*j32 15

如果创建/打开一个对象并允许继承该句柄,则允许继承句柄的子进程(例如,您可以bInheritHandles = TRUE为CreateProcess 指定)将具有这些句柄的副本.这些继承的句柄将具有与父句柄相同的句柄值.例如:

  • CreateEvent返回一个事件对象的句柄,句柄是0x1234.
  • 您允许继承该句柄.
  • 您创建一个继承句柄的子进程.
  • 该子进程现在可以使用句柄0x1234而无需调用CreateEventOpenEvent.例如,您可以在子进程的命令行中传递句柄值.

这对于未命名的对象很有用 - 因为它们未命名,其他进程无法打开它们.使用句柄继承子进程可以获取未命名对象的句柄(如果需要).


Har*_*ton 7

现有答案中尚未提出的一点是,允许子进程继承句柄不仅会影响子进程,还会影响子进程。它还可能影响句柄所引用的对象的生命周期。如果父进程退出,子进程中的句柄将使对象保持活动状态。

当允许子进程继承句柄时,您必须考虑这是否会导致对象的生存时间比应有的时间长;例如,某些应用程序只想允许一次运行一个实例,并且可能通过创建具有给定名称的事件对象并查看它是否已存在来实现这一点。如果他们创建一个继承该事件对象的子进程,并且比父进程寿命更长,则可能会导致误报。

更常见的是,继承的文件句柄可能会导致文件的使用时间(因此无法访问)比应有的时间长。

因此,最佳实践是:

另一方面,这有时也很有用。例如,如果您希望子进程算作父进程的实例,或者希望文件在子进程退出之前保持不可访问。另一个技巧是让子进程继承命名对象的句柄,然后使用该对象的存在或不存在来确定子进程是否仍然存在,而无需传递进程句柄或进程 ID。