当前线程句柄





5.00/5 (5投票s)
当你想要使用当前线程句柄时该怎么做
引言
当你需要获取当前线程的句柄时,可以使用 GetCurrentThread
,它会给你一个伪句柄,你不需要关闭它,因为它不是一个真正的引用计数句柄。文档中对此有明确说明。然而,我最近就遇到了这个问题。我想分享一下,以便其他人可以避免追查这个问题。
我的困惑
考虑以下示例
DWORD worker(void* ctx)
{
std::cout << "Thread id: " << GetThreadId((HANDLE)ctx) << std::endl;
return 0;
}
int main()
{
HANDLE hMainThread = GetCurrentThread();
std::cout << "Thread id: " << GetThreadId(hMainThread) << std::endl;
HANDLE hThread = CreateThread(NULL, 0, worker, hMainThread, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
}
事情是这样的
我没有仔细思考,就假设这个伪句柄只是实际句柄的一个弱引用(当前句柄的一个非引用计数副本),并且可以在工作线程中引用它。但实际上,它是一个特殊的常量,字面意思是“当提供此句柄值时,使用当前线程”。如果你将该特殊值传递到另一个线程,那么该值将转换为“那个”线程的线程句柄。
如果你阅读文档,它会明确说明这一点。只是我没有停下来思考这到底意味着什么。
获取真正的线程句柄
如果你想获取一个可以传递到另一个线程的真实句柄,请这样做
HANDLE hMainThread = NULL;
if (!DuplicateHandle(
GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&hMainThread,
0,
FALSE,
DUPLICATE_SAME_ACCESS)) {
cout << "Error " << GetLastError() << " cannot duplicate main handle." << endl;
return GetLastError();
}
当然,当你这样做时,你会得到一个 HANDLE
值,当你不再需要它时,你需要关闭它。
关注点
正如我所说,这没什么了不起的,文档也解释了这一点。但是,我花了一段时间才明白为什么我的 APC 被调度到错误的线程,也许我可以为其他人省去麻烦。:)
历史
- 2022年12月27日:初稿