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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2040768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:43:45  来源:igfitidea点击:

What does it mean: "A child-process can inherit the handle"?

windowswinapihandle

提问by Daniel Rikowski

There are some Win32 objects which according to the SDK can be "inherited" to the child-processes created by the given process. (Events, mutexes, pipes, ...)

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

What does that actually mean?

这实际上意味着什么?

Let's say I have a named event object, created with CreateEvent, one time with bInheritHandle == true, and another time == false.

假设我有一个命名的事件对象,它创建于CreateEvent,一次是bInheritHandle == true,另一次是== false

Now I start a child process. How do those two event handles affect the child process? In which scenarios do they differ?

现在我开始一个子进程。这两个事件句柄如何影响子进程?它们在哪些场景中有所不同?

回答by wj32

If you create/open an object and allow that handle to be inherited, child processes which are allowed to inherit handles (e.g. you can specify bInheritHandles = TRUEfor CreateProcess) will have copies of those handles. Those inherited handles will have the same handle values as the parent handles. So for example:

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

  • CreateEventreturns a handle to an event object, handle is 0x1234.
  • You allow that handle to be inherited.
  • You create a child process that inherits your handles.
  • That child process can now use handle 0x1234without having to call CreateEventor OpenEvent. You could for example pass the handle value in the command line of the child process.
  • CreateEvent返回一个事件对象的句柄,句柄是0x1234
  • 您允许继承该句柄。
  • 您创建一个继承您的句柄的子进程。
  • 该子进程现在可以使用 handle0x1234而无需调用CreateEventOpenEvent。例如,您可以在子进程的命令行中传递句柄值。

This is useful for unnamed objects - since they're unnamed, other processes can't open them. Using handle inheritance child processes can obtain handles to unnamed objects if you want them to.

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

回答by Harry Johnston

One point which has not been made in the existing answers is that allowing a child process to inherit handles doesn't only affect the child process; it may also affect the lifetime of the object to which the handles refer. If the parent process exits, the handles in the child process will keep the object alive.

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

When allowing a child process to inherit handles you must consider whether it will result in an object living longer than it should; for example, some applications only want to allow one instance to run at a time, and might do that by creating an event object with a given name and seeing whether it already exists. If they create a child process which inherits that event object, and outlives the parent, it could result in a false positive.

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

More commonly, an inherited handle to a file may result in the file remaining in use (and hence inaccessible) longer than it should have.

更常见的是,文件的继承句柄可能导致文件在使用中(因此无法访问)的时间超过其应有的时间。

For this reason, best practice is to:

因此,最佳做法是:

  • 将所有句柄设为不可继承,除非它们特别需要被继承。

  • 如果子进程不需要继承句柄,则传递FALSEfor bInheritHandles

  • 如果子进程确实需要继承句柄,则只允许它继承那些需要的特定句柄

On the other hand, this can occasionally be useful; for example, if you wantthe child process to count as an instance of the parent process, or for a file to remain inaccessible until the child has exited. Another trick is to have a child inherit a handle to a named object and then use the existence or non-existence of the object to determine whether the child is still alive, without having to pass around a process handle or process ID.

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

回答by dreamlax

If you create an event, and allow the handle to be inherited by child processes, then the child process can use the handle to the exact same object created by the parent. This can be used in a way where a child uses an event handle to signal to the parent when a task has been completed (there are many other uses for inheritable event object handles).

如果您创建一个事件,并允许子进程继承句柄,则子进程可以使用父进程创建的完全相同的对象的句柄。这可以用于在任务完成时子级使用事件句柄向父级发出信号的方式(可继承的事件对象句柄还有许多其他用途)。

EDIT: Removed disinformation.

编辑:删除虚假信息。