C++ 设置线程名称


为了调试方便,可以设置线程的名称,设置方法收集如下。

WINDOWS平台

方案一

参考
https://docs.microsoft.com/zh-cn/visualstudio/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2015

//  
// 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)

在下面的操作系统上可以使用SetThreadDescriptionGetThreadDescription设置和获取线程名。

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个函数可以实现prctlpthread_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
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中,可以使用 Windows API 函数 `GetThreadId()` 来根据程序名称获取线程 ID。具体步骤如下: 1. 使用 `CreateToolhelp32Snapshot()` 函数创建进程快照,获取当前正在运行的所有进程信息。 2. 遍历进程快照,根据进程名称获取进程 ID。 3. 使用 `OpenProcess()` 函数打开进程,获取进程句柄。 4. 使用 `CreateToolhelp32Snapshot()` 函数创建线程快照,获取当前进程中所有线程信息。 5. 遍历线程快照,根据进程 ID 和线程名称获取线程 ID。 6. 关闭进程和线程快照句柄,释放资源。 以下是示例代码: ```c++ #include <windows.h> #include <tlhelp32.h> #include <iostream> DWORD GetThreadIdByProcessNameAndThreadName(const std::wstring& processName, const std::wstring& threadName) { // 创建进程快照 HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnapshot == INVALID_HANDLE_VALUE) { std::cerr << "CreateToolhelp32Snapshot failed" << std::endl; return 0; } DWORD processId = 0; // 遍历进程快照,获取进程 ID PROCESSENTRY32 processEntry = {}; processEntry.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hProcessSnapshot, &processEntry)) { do { if (processName.compare(processEntry.szExeFile) == 0) { processId = processEntry.th32ProcessID; break; } } while (Process32Next(hProcessSnapshot, &processEntry)); } // 关闭进程快照句柄 CloseHandle(hProcessSnapshot); if (processId == 0) { std::cerr << "Process not found: " << processName << std::endl; return 0; } // 打开进程,获取句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); if (hProcess == NULL) { std::cerr << "OpenProcess failed" << std::endl; return 0; } DWORD threadId = 0; // 创建线程快照 HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hThreadSnapshot == INVALID_HANDLE_VALUE) { std::cerr << "CreateToolhelp32Snapshot failed" << std::endl; return 0; } // 遍历线程快照,获取线程 ID THREADENTRY32 threadEntry = {}; threadEntry.dwSize = sizeof(THREADENTRY32); if (Thread32First(hThreadSnapshot, &threadEntry)) { do { if (threadEntry.th32OwnerProcessID == processId) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadEntry.th32ThreadID); if (hThread != NULL) { // 获取线程名称 WCHAR threadNameBuffer[MAX_PATH] = {}; DWORD threadNameLength = GetThreadDescription(hThread, threadNameBuffer, MAX_PATH); if (threadNameLength > 0) { std::wstring threadNameActual(threadNameBuffer, threadNameLength); // 比较线程名称 if (threadName.compare(threadNameActual) == 0) { threadId = threadEntry.th32ThreadID; break; } } CloseHandle(hThread); } } } while (Thread32Next(hThreadSnapshot, &threadEntry)); } // 关闭线程快照句柄 CloseHandle(hThreadSnapshot); // 关闭进程句柄 CloseHandle(hProcess); return threadId; } ``` 调用示例: ```c++ DWORD threadId = GetThreadIdByProcessNameAndThreadName(L"myprocess.exe", L"mythread"); if (threadId != 0) { std::cout << "Thread ID: " << threadId << std::endl; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值