如何将名称设置为Win32线程?

我如何设置一个名称为Win32线程。 我没有find任何Win32 API来实现相同的。 基本上我想在日志文件中添加线程名称。 TLS(线程本地存储)是唯一的方法吗?

您始终可以将这些信息存储在合适的数据结构中。 使用散列或地图将GetThreadId()映射到此名称。 由于GetThreadId()始终是一个唯一的标识符,这工作得很好。

干杯!

当然,如果他创建了许多线程,那么hashmap将会慢慢填满并使用越来越多的内存,所以一些清理过程也可能是一件好事。

你是绝对正确的。 当一个线程死亡时,它在地图中的相应条目自然应该被删除。

这有帮助吗? 如何在本机代码中设置线程名称

在托管代码中,就像设置相应的Thread对象的Name属性一样简单。

http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.90).aspx

// // Usage: SetThreadName (-1, "MainThread"); // #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, char* threadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = threadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; __try { RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); } __except(EXCEPTION_EXECUTE_HANDLER) { } } 

Win32线程没有名称。 有一个微软惯例,应用程序提出包含线程名称的特殊的SEH异常。 这些异常可以被调试器拦截并用来指示线程名称。 几个答案涵盖了这一点。

但是,这一切都是由调试器处理的。 线程本身是无名的对象。 所以,如果你想把名字和你的线索联系起来,你必须开发你自己的机制。 虽然您可以使用线程本地存储,只会允许您从该线程中执行的代码获取名称。 所以线程ID和名称之间的全局映射似乎是最自然和有用的方法。

您可以使用线程本地存储对象来存储名称。 例如,

 __declspec( thread ) char threadName[32]; 

然后你可以写一个线程来读这个。 这在记录器应用程序中可能很有用,您可以在其中打印出每条消息的线程名称。 您可能想要在线程启动时立即写入该变量,并且抛出Microsoft异常( https://stackoverflow.com/a/10364541/364818 ),以便调试器也知道线程名称。

根据与微软调试团队负责人的讨论(详见下面的链接),SetThreadDescription API是微软公司将继续使用的API,以正式代码支持线程命名。 “正式”我的意思是一个MS支持的API命名线程,而不是目前的异常投掷黑客,目前只适用于在Visual Studio中运行一个进程。

此API从Windows 10(版本1607)开始可用。

但是,目前只有很少的工具支持,因此您设置的名称在Visual Studio或WinDbg调试器中将不可见。 但是到2017年4月,微软的xperf / WPA工具也支持它(通过这个API命名的线程将会在这些工具中正确显示它们的名字)。

如果您希望获得更好的支持,例如WinDbg,Visual Studio和崩溃转储文件,请使用以下链接投票支持:

https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/17608120-properly-support-native-thread-naming-via-the-sett

如果您想在调试器(windbg或visual studio)中看到您的线程的名称: http : //blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx

我不确定是否有反向方法来获取线程名称。 但是TLS听起来像是要走的路。

另一种方法是在线程的TEB的ArbitraryUserPointer字段中存储一个指向名字的指针。 这可以在运行时写入和读取。

有一个CodeProject文章标题为“调试与线程信息块” ,告诉你如何做到这一点。