为了调试方便,可以设置线程的名称,设置方法收集如下。
WINDOWS平台
方案一
//
// Usage: SetThreadName ((DWORD)-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, const char* threadName) {
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
__try{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER){
}
#pragma warning(pop)
}
方案二
参考
https://technet.microsoft.com/zh-cn/scriptcenter/mt774976(v=vs.95)
在下面的操作系统上可以使用SetThreadDescription
和GetThreadDescription
设置和获取线程名。
Requirements
Minimum supported client
Windows 10, version 1607 [desktop apps | UWP apps]
Minimum supported server
Windows Server 2016 [desktop apps | UWP apps]
示例代码:
HRESULT hr = SetThreadDescription(GetCurrentThread(), L"simulation_thread");
if (FAILED(hr))
{
// Call failed.
}
LINUX平台
主要有2个函数可以实现prctl
和pthread_setname_np
,在linux平台下线程名的长度是有限制的,不能超过16字节,最后有’\0’,也就是最多15个字节。
两个函数的使用方式有所不同,简单说明如下:
prctl:只能设置本线程的名称,传入参数线程名超出长度,会自动截断
pthread_setname_np:能设置指定线程的名称,传入参数线程名超出长度,不会自动截断,而是会返回错误码ERANGE(因为是非pthread标准实现,不同操作系统可能表现不一样)。
下面是摘自trafficserver的实现,可以根据自身需求自行调整实现。
参考实现:
https://github.com/apache/trafficserver/blob/8.1.x/include/tscore/ink_thread.h
https://github.com/apache/trafficserver/blob/master/include/tscore/ink_thread.h
// This define is from Linux's <sys/prctl.h> and is most likely very
// Linux specific... Feel free to add support for other platforms
// that has a feature to give a thread specific name / tag.
static inline void
ink_set_thread_name(const char *name)
{
#if defined(HAVE_PTHREAD_SETNAME_NP_1)
pthread_setname_np(name);
#elif defined(HAVE_PTHREAD_SETNAME_NP_2)
pthread_setname_np(pthread_self(), name);
#elif defined(HAVE_PTHREAD_SET_NAME_NP_2)
pthread_set_name_np(pthread_self(), name);
#elif defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_NAME)
prctl(PR_SET_NAME, name, 0, 0, 0);
#endif
}
static inline void
ink_get_thread_name(char *name, size_t len)
{
#if defined(HAVE_PTHREAD_GETNAME_NP)
pthread_getname_np(pthread_self(), name, len);
#elif defined(HAVE_PTHREAD_GET_NAME_NP)
pthread_get_name_np(pthread_self(), name, len);
#elif defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
prctl(PR_GET_NAME, name, 0, 0, 0);
#else
snprintf(name, len, "0x%" PRIx64, (uint64_t)ink_thread_self());
#endif
}