DuplicateHandle,为什么要复制而不是仅仅获取?

发布于 2024-08-19 14:38:55 字数 114 浏览 4 评论 0原文

为什么一个进程想要从 Win32API 调用 DuplicateHandle,并从另一个进程获取它,而不是仅仅获取某个对象本身的句柄?

调用 DuplicateHandle 或其他东西有什么好处吗?

Why would a process want to call DuplicateHandle from the Win32API, and get it from another process instead of just acquiring the handle on some object itself?

Is there some advantage to calling DuplicateHandle or something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夜声 2024-08-26 14:38:55

您可以在“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 章中讨论)可以完成此转换

You may find the answer in Chapter 6.8 of 'Programming Applications for Microsoft Windows'.

Gaining a Sense of One's Own Identity
Sometimes you might need to acquire a real handle to a thread instead of a pseudo-handle. By "real," I mean a handle that unambiguously identifies a unique thread. Examine the following code:

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...
}

Can you see the problem with this code fragment? The idea is to have the parent thread pass to the child thread a thread handle that identifies the parent thread. However, the parent thread passes a pseudo-handle, not a real handle. When the child thread begins executing, it passes the pseudo-handle to the GetThreadTimes function, which causes the child thread to get its own CPU times, not the parent thread's CPU times. This happens because a thread pseudo-handle is a handle to the current thread— that is, a handle to whichever thread is making the function call.

To fix this code, we must turn the pseudo-handle into a real handle. The DuplicateHandle function (discussed in Chapter 3) can do this transformation

征﹌骨岁月お 2024-08-26 14:38:55

DuplicateHandle 的一种可能用途是在 32 位进程和 64 位进程之间复制句柄。

注意:不能在 I/O 完成端口或套接字上使用。

One possible use of DuplicateHandle is to duplicate a handle between a 32-bit process and a 64-bit process.

Note: cannot be used on I/O Completion ports or Sockets.

明媚殇 2024-08-26 14:38:55

DuplicateHandle 的另一个用途是当文件使用 FileOptions.DeleteOnClose 时在多个进程中打开文件。 (如果使用文件路径打开文件,则此类文件无法由多个进程打开)

请参阅我的答案 https://stackoverflow .com/a/36606283/2221472

Another use of DuplicateHandle is to open a file in multiple processes when the file uses FileOptions.DeleteOnClose. (such a file cannot be opened by multiple processes if the file path is used to open the file)

See my answer at https://stackoverflow.com/a/36606283/2221472

∞梦里开花 2024-08-26 14:38:55

请参阅 MSDN 上关于 '重复句柄'。我能想到的最好的方法是这样的,如果您愿意的话,可以打个比方 - 假设您使用 CreateHandle 例程打开一个仅用于写入的文件,然后调用 DuplicateHandle 将句柄传递到另一个线程,在该线程中该线程将从文件中,只有句柄被复制,因此线程不必再次调用 CreateHandle...

See here on the MSDN what it has to say about the usage of 'DuplicateHandle'. The best way I can think of it is this way, an analogy if you like - suppose you open a file using the CreateHandle routine for writing only, then you call DuplicateHandle to pass the handle onto another thread in which the thread will read from the file, only the handle is duplicated hence the thread does not have to call CreateHandle again...

诗酒趁年少 2024-08-26 14:38:55

当不存在句柄的任何“正常获取”时,经常使用DuplicateHandle

  • 该对象没有名称(例如匿名管道、匿名文件映射、套接字)
  • 该对象在一种不是永久唯一的方式,因此使用它会创建竞争条件(进程 ID、线程 ID、文件名)
  • 需要使用句柄的进程没有直接打开对象的权限。
  • 该对象不允许非独占打开(串行端口设备、FILE_SHARE_NONE、FILE_DELETE_ON_CLOSE)

DuplicateHandle is frequently used when there doesn't exist any "normal acquisition" of the handle:

  • The object doesn't have a name (e.g. anonymous pipes, anonymous file mappings, sockets)
  • The object is identified in a way that is not permanently unique, so that using it would create a race condition (process IDs, thread IDs, filenames)
  • The process that needs to use the handle doesn't have permission to directly open the object.
  • The object doesn't allow opening non-exclusively (serial port devices, FILE_SHARE_NONE, FILE_DELETE_ON_CLOSE)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文