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

Can*_*pus 17 windows winapi multithreading

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

Gis*_*shu 30

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

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

  • 作为http://thetweaker.wordpress.com/2009/04/10/naming-threads/ notes,它们都是通过将线程名称存储在调试器数据结构中来实现的.因此,没有调试器,名称将不会被存储,并且不会用于记录目的.令人讨厌的错误:当你尝试调试它时,它会突然再次运行. (4认同)
  • 我想它只适用于Visual Studio调试器来显示线程名称. (2认同)
  • 其他调试器也纷纷效仿并响应相同的信号 (2认同)

faz*_*ang 19

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)
  {
  }
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*nan 10

Win32线程没有名称.有一种Microsoft约定,即应用程序引发包含线程名称的特殊SEH异常.这些异常可以被调试器拦截并用于指示线程名称.一些答案涵盖了这一点.

但是,这一切都由调试器处理.线程本身是无名对象.因此,如果要将名称与线程关联,则必须开发自己的机制.虽然您可以使用线程本地存储,但只允许您从该线程中执行的代码中获取名称.因此,线程ID和名称之间的全局映射似乎是最自然和最有用的方法.


Chr*_*ine 5

根据与Microsoft调试团队负责人的讨论(有关详细信息,请参见下面的链接),SetThreadDescription API是Microsoft今后将使用的API,以正式支持本机代码中的线程命名。“正式”是指用于命名线程的MS支持的API,与当前仅在Visual Studio中运行进程时才起作用的当前引发异常的黑客相反。

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

但是,当前几乎没有工具支持,因此您设置的名称在Visual Studio或WinDbg调试器中将不可见。但是,自2017年4月起,Microsoft 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


ral*_*nja -2

您始终可以将这些信息存储在合适的数据结构中。使用哈希或映射将 GetThreadId() 映射到此名称。由于 GetThreadId() 始终是唯一标识符,因此效果很好。

干杯!

当然,如果他创建许多线程,则该哈希图将慢慢填满并使用越来越多的内存,因此一些清理过程可能也是一件好事。

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