打开/关闭手柄时会发生啥?

Posted

技术标签:

【中文标题】打开/关闭手柄时会发生啥?【英文标题】:What happen when you open/close a handle?打开/关闭手柄时会发生什么? 【发布时间】:2015-11-23 13:58:18 【问题描述】:

我被介绍给 C++。我对“句柄”的想法感到困惑这是我今天写的一个小sn-p:

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, a valid pid);
    printf("%d", hProcess);

我发现每次输出都是“48”。这是有道理的,因为句柄是数组索引等资源的标识符。但即使我将 PROCESS_ALL_ACCESS 替换为其他标志,返回值仍然相同。打开手柄时究竟发生了什么?操作系统如何知道句柄的访问权限?如果句柄是资源的标识符,为什么下面的代码不起作用?

    HANDLE hProces = 48;

此外,调用 CloseHandle(hProcess) 时发生了什么?为什么输出还是48?

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, a valid pid);
    CloseHandle(hProcess);
    printf("%d\n", hProcess);

【问题讨论】:

一个把手就像一个停车位。你开车说“我想停一辆蓝色的本田思域”,然后对方说“停在 48 号空间”。如果你开着一辆红色的丰田凯美瑞开车,这个人可能仍然会说“去 48 号空间停车”。但是,如果您只是开车进入并停在 48 号停车位而不告诉任何人,那么当您稍后回来说“我想要 48 号停车位的车”时,停车人会说“我不知道你是什么谈。”合上把手是在告诉停车的人,“我现在要开车了。我在 48 号车位。” 或者它就像一个把手,您可以将它连接到您碰巧拥有的任何锅上。您需要拿起一个锅,抓住一个把手并将其连接到锅上。直到你拆下它,那个把手才能抓住那个锅。 【参考方案1】:

hProcess 只是一个值关联一个进程。句柄本身由操作系统管理并与进程相关联。

打开句柄时到底发生了什么?

OpenProcess 在操作系统的某些数据结构中创建一个条目,执行初始化工作,并将句柄 (48) 与该条目相关联。

操作系统如何知道特定句柄的句柄的访问权限?

它将它们存储在句柄所指的单独数据结构中(例如,如果它是一个表,则句柄是该表的索引)。句柄的值独立于与其关联的访问权限。

如果句柄是资源的标识符,为什么下面的代码不起作用?

HANDLE hProces = 48;

因为操作系统还没有添加对应的条目,所以句柄48没有关联任何东西。

举个例子,如果你这样做了

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, a valid pid);
HANDLE alias = hProcess;

alias 将引用与 hProcess 相同的过程。

为什么输出还是48?

CloseHandle 从数据结构中删除该条目并解除句柄与条目的关联。1 打印hProcess 定义明确。它只是一个值,不会被CloseHandle 扩充。只有关联的条目和条目的句柄(48)的含义被删除。


我认为您可以想象整个事情是这样的:有一个数据结构,其中包含您的流程数据,其中包含已打开流程的数据。句柄是指向这些进程条目的“指针”。如果存在进程条目,则句柄指向某个众所周知的进程。但是,如果不是,则句柄确实指向一个进程。就像指针一样:

char* ptr;

    char c = 'a'; /* similar to the call to OpenProcess itsself */
    ptr = &c;    /* similar to hProcess initialized with the return value
                  * of OpenProcess */
    /* c goes out of scope, similar to CloseHandle */

1 正如@IInspectable 在 cmets 中对这个答案所说,这实际上并不完全正确。操作系统为句柄维护一个计数器,该计数器计算引用关联进程的实体数。 OpenProcessCloseHandle 仅分别递增/递减该计数器,以使句柄的多个“拥有者”成为可能。

【讨论】:

其实CloseHandle会减少被引用对象的引用计数。当引用计数达到零时,被引用的对象被销毁,并且它的条目从内核控制的列表中删除。 @IInspectable 比我想象的更类似于 Linux...会更新,谢谢。 @IInspectable 已编辑。请您看一下并检查其正确性吗? 不,这不太对。手柄不计算在内。如果您打开同一个进程的两个句柄,它们将具有不同的值。我认为,您的原始文本很好,只要您明确说明您是在谈论句柄而不是句柄所指的对象。【参考方案2】:

我们可以猜测局部变量hProcess 没有被CloseHandle 函数改变。 您必须检查CloseHandle 的返回值才能知道此功能是否有效,但您不能依赖hProcess 的值。

【讨论】:

那么当你关闭一个句柄时到底发生了什么?

以上是关于打开/关闭手柄时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

手机屏幕关闭时会发生啥?

分配生成器功能时会发生啥? [关闭]

关闭 C++ 控制台应用程序时会发生啥

当自动关闭资源时尝试使用资源引发异常以及异常时会发生啥

在 c++ 中将对象分配给一个值时会发生啥 [关闭]

当我将任何命令通过管道传输到 telnet 会话时会发生啥,为啥会话会关闭