为什么进程要从 Win32API 调用 DuplicateHandle,并从另一个进程获取它,而不是仅仅获取某个对象本身的句柄?
调用 DuplicateHandle 有什么好处吗?
您可以在“为 Microsoft Windows 编程应用程序”的第 6.8 章中找到答案。
获得对自己身份的
认识 有时您可能需要获取线程的真实句柄而不是伪句柄。我所说的“真实”是指明确标识唯一线程的句柄。检查以下代码:
DWORD WINAPI ParentThread(PVOID pvParam) {
HANDLE hThreadParent = GetCurrentThread();
CreateThread(NULL, 0, ChildThread, (PVOID) hThreadParent, 0, NULL);
// Function continues...
}
DWORD WINAPI ChildThread(PVOID pvParam) {
HANDLE hThreadParent = (HANDLE) pvParam;
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
GetThreadTimes(hThreadParent,
&ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
// Function continues...
}
你能看出这个代码片段的问题吗?这个想法是让父线程向子线程传递一个标识父线程的线程句柄。但是,父线程传递的是伪句柄,而不是真正的句柄。当子线程开始执行时,它会将伪句柄传递给 GetThreadTimes 函数,这会导致子线程获取自己的 CPU 时间,而不是父线程的 CPU 时间。发生这种情况是因为线程伪句柄是当前线程的句柄——也就是说,是对正在进行函数调用的任何线程的句柄。
要修复此代码,我们必须将伪句柄转换为真实句柄。DuplicateHandle 函数(在第 3 章中讨论)可以进行这种转换
请参阅 MSDN 上的此处关于“ DuplicateHandle ”的用法的说明。我能想到的最好的方法就是这样,如果你愿意,可以类比 - 假设你使用 CreateHandle 例程打开一个文件,然后你调用 DuplicateHandle 将句柄传递给另一个线程,该线程将从文件,只有句柄被复制,因此线程不必再次调用 CreateHandle ......
一种可能的用途DuplicateHandle
是在 32 位进程和 64 位进程之间复制句柄。
注意:不能用于 I/O 完成端口或套接字。
DuplicateHandle 的另一个用途是在文件使用FileOptions.DeleteOnClose
. (如果使用文件路径打开文件,这样的文件不能被多个进程打开)