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

Kel*_*ang 3 c++ winapi handle visual-c++

我被介绍给C++.我对"处理"的想法感到困惑这是我今天写的一个小片段:

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, a valid pid);
    printf("%d", hProcess);
Run Code Online (Sandbox Code Playgroud)

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

    HANDLE hProces = 48;
Run Code Online (Sandbox Code Playgroud)

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

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

cad*_*luk 5

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

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

OpenProcess在OS的某些数据结构中创建一个条目,执行初始化操作,并将handle(48)与条目相关联.

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

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

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

HANDLE hProces = 48;
Run Code Online (Sandbox Code Playgroud)

由于操作系统尚未添加相应的条目,因此句柄48不与任何内容相关联.

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

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, a valid pid);
HANDLE alias = hProcess;
Run Code Online (Sandbox Code Playgroud)

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 */
Run Code Online (Sandbox Code Playgroud)

1正如@IInspectable在对这个答案的评论中所说,这实际上并不完全正确.操作系统维护句柄的计数器,该计数器计算引用相关进程的实体数.OpenProcess并且CloseHandle只增加/减少该计数器,分别使句柄的多个"拥有者"成为可能.