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(线程本地存储)是唯一的方法吗?
9 个解决方案
#1
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.
你是绝对正确的。当线程死亡时,自然会删除地图中相应的条目。
#2
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属性一样简单。
#3
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)
{
}
}
#4
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和名称之间的全局映射似乎是最自然和最有用的方法。
#5
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://*.com/a/10364541/364818) so that the debugger also knows the thread name.
然后你可以从一个线程中写入和读取它。这在记录器应用程序中可能很有用,在该应用程序中,您要打印每个消息的线程名称。您可能希望在线程启动后立即编写此变量,并抛出Microsoft异常(https://*.com/a/10364541/364818),以便调试器也知道线程名称。
#6
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和崩溃转储文件中,请使用以下链接投票:
#7
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听起来像是要走的路。
#8
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文章向您展示了如何执行此操作。
#9
If your application runs on Windows version 1607+, you can use SetThreadDescription()
如果您的应用程序在Windows版本1607+上运行,则可以使用SetThreadDescription()
#1
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.
你是绝对正确的。当线程死亡时,自然会删除地图中相应的条目。
#2
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属性一样简单。
#3
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)
{
}
}
#4
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和名称之间的全局映射似乎是最自然和最有用的方法。
#5
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://*.com/a/10364541/364818) so that the debugger also knows the thread name.
然后你可以从一个线程中写入和读取它。这在记录器应用程序中可能很有用,在该应用程序中,您要打印每个消息的线程名称。您可能希望在线程启动后立即编写此变量,并抛出Microsoft异常(https://*.com/a/10364541/364818),以便调试器也知道线程名称。
#6
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和崩溃转储文件中,请使用以下链接投票:
#7
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听起来像是要走的路。
#8
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文章向您展示了如何执行此操作。
#9
If your application runs on Windows version 1607+, you can use SetThreadDescription()
如果您的应用程序在Windows版本1607+上运行,则可以使用SetThreadDescription()