windows 如何将名称设置为 Win32 线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/905876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set name to a Win32 Thread?
提问by Canopus
How do I set a name to a Win32 thread. I did'nt find any Win32 API to achieve the same. Basically I want to add the Thread Name in the Log file. Is TLS (Thread Local Storage) the only way to do it?
如何为 Win32 线程设置名称。我没有找到任何 Win32 API 来实现相同的目标。基本上我想在日志文件中添加线程名称。TLS(线程本地存储)是唯一的方法吗?
采纳答案by ralphtheninja
You can always store this information for yourself in a suitable data structure. Use a hash or a map to map GetThreadId() to this name. Since GetThreadId() is always a unique identifier, this works just fine.
您始终可以将这些信息自己存储在合适的数据结构中。使用哈希或映射将 GetThreadId() 映射到此名称。由于 GetThreadId() 始终是唯一标识符,因此它可以正常工作。
Cheers !
干杯!
Of course, if he's creating many threads, that hashmap will slowly fill up and use more and more memory, so some cleanup procedure is probably a good thing as well.
当然,如果他创建了很多线程,hashmap 会慢慢填满并使用越来越多的内存,所以一些清理过程可能也是一件好事。
You're absolutely right. When a thread dies, it's corresponding entry in the map should naturally be removed.
你是绝对正确的。当一个线程死亡时,它在地图中的相应条目应该自然被删除。
回答by Gishu
Does this help ? How to: Set a Thread Name in Native Code
这有帮助吗? 如何:在本机代码中设置线程名称
In managed code, it is as easy as setting the Name property of the corresponding Thread object.
在托管代码中,就像设置相应 Thread 对象的 Name 属性一样简单。
回答by fazhang
http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.90).aspx
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)
{
}
}
回答by David Heffernan
Win32 threads do not have names. There is a Microsoft convention whereby applications raise special SEH exceptions containing a thread name. These exceptions can be intercepted by debuggers and used to indicate the thread name. A couple of the answers cover that.
Win32 线程没有名称。有一个 Microsoft 约定,应用程序由此引发包含线程名称的特殊 SEH 异常。这些异常可以被调试器拦截并用于指示线程名称。一些答案涵盖了这一点。
However, that is all handled by the debugger. Threads themselves are nameless objects. So, if you want to associate names with your threads, you'll have to develop your own mechanism. Whilst you could use thread local storage that will only allow you to obtain the name from code executing in that thread. So a global map between thread ID and the name would seem like the most natural and useful approach.
但是,这一切都由调试器处理。线程本身是无名的对象。因此,如果要将名称与线程相关联,则必须开发自己的机制。虽然您可以使用线程本地存储,但它只允许您从在该线程中执行的代码中获取名称。因此,线程 ID 和名称之间的全局映射似乎是最自然和最有用的方法。
回答by Chris Kline
According to discussion with the Microsoft debugging team leads (see link below for details) the SetThreadDescription API is the API that will be used going forward by Microsoft to support thread naming officially in native code. By "officially" I mean an MS-supported API for naming threads, as opposed to the current exception-throwing hack that currently only works while a process is running in Visual Studio.
根据与 Microsoft 调试团队负责人的讨论(有关详细信息,请参见下面的链接),SetThreadDescription API 是 Microsoft 将使用的 API,用于在本机代码中正式支持线程命名。“正式地”我指的是 MS 支持的用于命名线程的 API,而不是当前仅在进程在 Visual Studio 中运行时才有效的异常抛出 hack。
This API became available starting in Windows 10, version 1607.
此 API 从 Windows 10 版本 1607 开始可用。
Currently, however, there is very little tooling support, so the names you set won't be visible in the Visual Studio or WinDbg debuggers. As of April 2017, however, the Microsoft xperf/WPA tools do support it (threads named via this API will have their names show up properly in those tools).
但是,目前很少有工具支持,因此您设置的名称在 Visual Studio 或 WinDbg 调试器中不可见。但是,截至 2017 年 4 月,Microsoft xperf/WPA 工具确实支持它(通过此 API 命名的线程将在这些工具中正确显示它们的名称)。
If you would like to see this gain better support, such as in WinDbg, Visual Studio, and crash dump files, please vote for it using this link:
如果您希望看到它获得更好的支持,例如在 WinDbg、Visual Studio 和故障转储文件中,请使用此链接投票:
回答by Mark Lakata
You can use a thread-local storage object to store the name. For example,
您可以使用线程本地存储对象来存储名称。例如,
__declspec( thread ) char threadName[32];
Then you can write and read this from a thread. This might be useful in a logger application, where you want to print out the name of the thread for every message. You probably want to write this variable as soon as the thread starts, and also throw the Microsoft exception (https://stackoverflow.com/a/10364541/364818) so that the debugger also knows the thread name.
然后你可以从一个线程中编写和读取它。这在记录器应用程序中可能很有用,您希望在其中打印出每条消息的线程名称。您可能希望在线程启动后立即写入此变量,并抛出 Microsoft 异常 ( https://stackoverflow.com/a/10364541/364818),以便调试器也知道线程名称。
回答by Marcos Marin
If your application runs on Windows version 1607+, you can use SetThreadDescription()
如果您的应用程序在 Windows 1607+ 版本上运行,则可以使用SetThreadDescription()
回答by Chris Kline
Another way to do this is to store a pointer to the name in the ArbitraryUserPointer field of the TEB of the thread. This can be written to and read from at runtime.
另一种方法是在线程的 TEB 的 ArbitraryUserPointer 字段中存储指向名称的指针。这可以在运行时写入和读取。
There's a CodeProject article titled "Debugging With The Thread Information Block"that shows you how to do this.
有一篇标题为“使用线程信息块调试”的 CodeProject 文章向您展示了如何执行此操作。
回答by selbie
If you want to see the name of your thread in the debugger (windbg or visual studio): http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx
如果您想在调试器(windbg 或 Visual Studio)中查看线程的名称:http: //blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx
I'm not actually sure if there's a reverse method to get the thread name. But TLS sounds like the way to go.
我实际上不确定是否有反向方法来获取线程名称。但 TLS 听起来像是要走的路。