为提升线程命名?

Posted

技术标签:

【中文标题】为提升线程命名?【英文标题】:Give a name to a boost thread? 【发布时间】:2010-07-27 09:14:46 【问题描述】:

是否可以为boost::thread 命名,以便调试器表和崩溃日志更具可读性?怎么样?

【问题讨论】:

【参考方案1】:

您需要访问底层线程原语并以系统相关方式分配名称。调试和崩溃日志本质上是依赖于系统的,而 boost::thread 更多的是关于非系统依赖,即关于可移植性。

似乎 (http://www.boost.org/doc/libs/1_43_0/doc/html/thread.html) 没有记录在案的方式来访问提升线程的底层系统资源。 (但我自己从未使用过它,所以我可能会错过一些东西。)

编辑:(正如大卫在评论中所写)http://www.boost.org/doc/libs/1_43_0/doc/html/thread/thread_management.html#thread.thread_management.thread.nativehandle

【讨论】:

+1, boost::thread 有一个native_handle 方法,可用于检索线程的本机 API 句柄。您需要深入研究线程库以了解它返回的特定类型以及有关如何使用该句柄为其命名的 API 文档... 对于 Linux:***.com/questions/778085/… 对于 Windows:***.com/questions/905876/… 对于 Mac OS X:***.com/questions/2057960/… "... 以系统依赖的方式" 使用系统 API 对线程执行任何操作也是如此,例如创建它。提升的重点是将这些不同平台相关的 API 包装在一个可移植的 API 中。正如您所说,“boost::thread 是......关于可移植性”。这是支持具有“设置线程名称”方法的 boost 中的一个参数。【参考方案2】:

我在 Win32 + VS2010 上使用 boost 1.50.0,thread::native_handle 包含我无法与系统中的任何内容配对的数字。另一方面,thread::get_id() 方法直接以十六进制字符串的形式返回 Windows 线程 ID。请注意,返回的值是特定于平台的。以下代码在 Boost 1.50.0 + Win32 + VS2010 下工作。部分代码复用自msdn

const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
typedef struct THREADNAME_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 threadId, const char* threadName) 
    THREADNAME_INFO info;
    info.dwType = 0x1000;
    info.szName = threadName;
    info.dwThreadID = threadId;
    info.dwFlags = 0;
    __try 
        RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
    
    __except(EXCEPTION_EXECUTE_HANDLER) 
    

void SetThreadName(boost::thread::id threadId, std::string threadName) 
    // convert string to char*
    const char* cchar = threadName.c_str();
    // convert HEX string to DWORD
    unsigned int dwThreadId;
    std::stringstream ss;
    ss << std::hex << threadId;
    ss >> dwThreadId;
    // set thread name
    _SetThreadName((DWORD)dwThreadId, cchar);

这样调用:

boost::thread* thr = new boost::thread(boost::bind(...));
SetThreadName(thr->get_id(), "MyName");

【讨论】:

您缺少THREADNAME_INFO 结构和MS_VC_EXCEPTION。没有更好的方法从 boost::thread::id 中获取数字吗?哎呀。 对不起,我不知道它是怎么发生的,现在应该完成了。至于线程号 - 我不知道。 Boost 文档说根本没有办法...... 您可以通过传递 GetThreadId(在 中)本机句柄来获取线程 ID,该句柄可以从 boost 线程中获取。从那里您可以执行 RaiseException 操作。 GetThreadId 虽然更现代,但我认为您将无法在 XP 上运行。如果您不能使用 GetThreadId,还有一种方法可以从 boost::thread:id 中获取私有 unsigned int - 但这是非常邪恶的。 是的,如前所述 - 使用 tha native_handle 和 GetThreadId 我得到了一个与应用程序 threadId 不对应的数字(尽管它是一个有效的系统 threadid)。所以这对我不起作用。 我的意思是获得的threadID指向一个现有的线程,但不是我的应用程序创建的。【参考方案3】:

有一个建议将其添加到启动缓慢的 boost 中: https://github.com/boostorg/thread/issues/84

【讨论】:

以上是关于为提升线程命名?的主要内容,如果未能解决你的问题,请参考以下文章

为啥线程在进程间通信期间会破坏命名管道?

删除不必要的命名空间(使用)指令是不是有性能提升?

提升序列化和命名空间

提升进程间命名互斥信号量文件权限[重复]

C++ MFC 命名线程,以便 Procmon 可以看到它们

如何重命名提升属性树中的节点/元素?