如何为Win32线程设置名称。我没有找到任何Win32 API来实现相同的目标。基本上我想在日志文件中添加线程名称。 TLS(线程本地存储)是唯一的方法吗?
答案 0 :(得分:31)
这有帮助吗? How to: Set a Thread Name in Native Code
在托管代码中,它就像设置相应Thread对象的Name属性一样简单。
答案 1 :(得分:20)
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)
{
}
}
答案 2 :(得分:10)
Win32线程没有名称。有一种Microsoft约定,即应用程序引发包含线程名称的特殊SEH异常。这些异常可以被调试器拦截并用于指示线程名称。一些答案涵盖了这一点。
但是,这一切都由调试器处理。线程本身是无名对象。因此,如果要将名称与线程关联,则必须开发自己的机制。虽然您可以使用线程本地存储,但只允许您从该线程中执行的代码中获取名称。因此,线程ID和名称之间的全局映射似乎是最自然和最有用的方法。
答案 3 :(得分:4)
您可以使用线程本地存储对象来存储名称。例如,
__declspec( thread ) char threadName[32];
然后你可以从一个帖子中写下来。这在记录器应用程序中可能很有用,在该应用程序中,您要打印每个消息的线程名称。您可能希望在线程启动后立即编写此变量,并抛出Microsoft异常(https://stackoverflow.com/a/10364541/364818),以便调试器也知道线程名称。
答案 4 :(得分:1)
如果要在调试器(windbg或visual studio)中查看线程的名称: http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx
我真的不确定是否有反向方法来获取线程名称。但TLS听起来像是要走的路。
答案 5 :(得分:1)
另一种方法是在线程的TEB的ArbitraryUserPointer字段中存储指向名称的指针。这可以在运行时写入和读取。
有一篇名为"Debugging With The Thread Information Block"的CodeProject文章向您展示了如何执行此操作。
答案 6 :(得分:0)
如果您的应用程序在Windows 1607+版本上运行,则可以使用SetThreadDescription()
答案 7 :(得分:-1)
您始终可以将此信息存储在合适的数据结构中。使用散列或映射将GetThreadId()映射到此名称。由于GetThreadId()始终是唯一标识符,因此可以正常工作。
干杯!
当然,如果他创造了很多 线程,hashmap将慢慢填充 起来并使用越来越多的内存,所以 一些清理程序可能是一个 也是好事。
你是对的。当线程死亡时,地图中相应的条目自然会被删除。