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

时间:2009-05-25 08:32:04

标签: windows multithreading winapi

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

8 个答案:

答案 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将慢慢填充   起来并使用越来越多的内存,所以   一些清理程序可能是一个   也是好事。

你是对的。当线程死亡时,地图中相应的条目自然会被删除。