我是否必须关闭子进程稍后拥有的继承句柄?
微软在这里采取了谨慎的态度。在他们的文章中,“使用重定向输入创建子进程并输出”,他们说:
当该进程终止时,剩余的打开句柄将被清除。
为了避免大型应用程序中的资源泄漏,请显式关闭句柄。
这是完全没用的。什么柄?在哪个过程中?
我想弄清楚这个问题。
当在父进程中使用 SECURITY_ATTRIBUTES.bInheritHandle = TRUE
创建句柄时,子进程可以看到并使用它,并且该句柄在两个进程中具有相同的值和访问权限。
但是它是相同的句柄,还是碰巧具有相同数字表示形式的副本?
如果我将 hRead
句柄传递给子进程,以便它可以读取一个管道,子进程关闭了句柄,我还需要从父进程中关闭它吗?它不会从子进程下擦除管道吗?
我的实验表明,在子进程关闭后尝试关闭传递给子进程的 hRead
句柄时,CloseHandle
返回成功。这有力地证明了“是的,你应该关闭它”。但是,我希望在这里得到更可靠的建议。
Microsoft played safe here. In their article, "Creating a Child Process with Redirected Input and Output", they are saying:
The remaining open handles are cleaned up when this process terminates.
To avoid resource leaks in a larger application, close handles explicitly.
Which is perfectly useless. What handles? In which process?
I want to get my head around it.
When a handle is created in parent process with SECURITY_ATTRIBUTES.bInheritHandle = TRUE
, a child process can see and use it, and the handle has the same value and access rights in both processes.
But is it the same handle, or is it a copy that happen to have same numerical representation?
If I pass a hRead
handle to a child process so that it can read from a pipe, and the child process closes the handle, do I also need to close it from the parent process? Will it not wipe the pipe from under the child process?
My experiments show that CloseHandle
returns success when trying to close a hRead
handle passed to the child after the child has closed it. This argues strongly for Yes, you should close it. However, I would appreciate a more solid advice here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你说得一中要害。 Win32 句柄充当对底层内核模式对象的用户模式引用。对新对象和现有对象的句柄(引用)通常通过某种 CreateXXX 调用创建 - 通过调用 DuplicateHandle - {或将句柄标记为可继承并创建一个新进程 - 将句柄从当前进程复制到子进程 - 确保句柄值相同。}
此时,(至少)有两个对内核对象的引用,这两个引用都需要关闭以解锁对象并释放任何消耗的资源。
You hit the nail on the head there. Win32 handles act as user mode references to an underlying kernel mode object. Handles (references) to new and existing objects are typically created via some kind of CreateXXX call - additional references can be created in the current, or other processes, by calling DuplicateHandle - {or marking a handle as inheritable and creating a new process - which duplicates a handle from the current process into the child process - ensuring that the handle value is identical.}
At that point, there are (at least) two references to the kernel object, both of which need to be closed to unlock the object and free any consumed resources.