在Win10之前,Windows平台开发没有一个标准的API给一个线程命名。虽然我们可以自己在线程局部存储(Thread Local Storage)里设置一个线程名变量,但是调试器并不认这个线程名变量。如果要想调试器能够知道你的线程名,微软给出了一个比较hack的解决方案,就是抛出一个特殊异常来告诉调试器线程名。这个文章就是介绍这个方法,在本机代码中设置线程名称
#include <windows.h>
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName(DWORD dwThreadID, const char* threadName) {
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
__try{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER){
}
#pragma warning(pop)
}
Win10出了一个SetThreadDescription API来设置线程的名字,相比之前太方便了:
auto set_thread_description_func =
reinterpret_cast<SetThreadDescription>(::GetProcAddress(
::GetModuleHandle(L"Kernel32.dll"), "SetThreadDescription"));
if (set_thread_description_func) {
set_thread_description_func(::GetCurrentThread(),
base::UTF8ToWide(name).c_str());
}
参考: