打开/关闭手柄时会发生啥?
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 中对这个答案所说,这实际上并不完全正确。操作系统为句柄维护一个计数器,该计数器计算引用关联进程的实体数。 OpenProcess
和 CloseHandle
仅分别递增/递减该计数器,以使句柄的多个“拥有者”成为可能。
【讨论】:
其实CloseHandle
会减少被引用对象的引用计数。当引用计数达到零时,被引用的对象被销毁,并且它的条目从内核控制的列表中删除。
@IInspectable 比我想象的更类似于 Linux...会更新,谢谢。
@IInspectable 已编辑。请您看一下并检查其正确性吗?
不,这不太对。手柄不计算在内。如果您打开同一个进程的两个句柄,它们将具有不同的值。我认为,您的原始文本很好,只要您明确说明您是在谈论句柄而不是句柄所指的对象。【参考方案2】:
我们可以猜测局部变量hProcess
没有被CloseHandle
函数改变。
您必须检查CloseHandle
的返回值才能知道此功能是否有效,但您不能依赖hProcess
的值。
【讨论】:
那么当你关闭一个句柄时到底发生了什么?以上是关于打开/关闭手柄时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章