给Boost线程命名?

17

是否可以给boost::thread命名,以便调试器表格和崩溃日志更易读?如何实现?

3个回答

7
您需要访问底层线程原语并以系统相关的方式分配名称。调试和崩溃日志本质上是系统相关的,而boost::thread更多地关注于非系统依赖性,即可移植性。
看起来(http://www.boost.org/doc/libs/1_43_0/doc/html/thread.html),没有记录的方法可以访问boost线程的底层系统资源。(但我自己从未使用过,所以可能会漏掉一些东西。)
编辑:(正如David在评论中写的那样)http://www.boost.org/doc/libs/1_43_0/doc/html/thread/thread_management.html#thread.thread_management.thread.nativehandle

6
boost::thread有一个native_handle方法,可以用来获取线程的本地API句柄。您需要查看线程库以了解它返回的特定类型以及有关如何使用该句柄为其命名的API文档... - David Rodríguez - dribeas
14
针对Linux:https://dev59.com/questions/mXRA5IYBdhLWcg3w8SeJ - moala
9
对于Windows系统:https://dev59.com/kXNA5IYBdhLWcg3wk-6A该链接提供了如何为Win32线程设置名称的方法。 - moala
7
针对 Mac OS X:https://dev59.com/questions/tnI95IYBdhLWcg3w_zWs - moala
2
"...以系统相关的方式"。对于使用系统API对线程执行任何操作,例如创建线程,情况也是如此。boost的重点是将这些不同平台相关的API封装在一个单一的可移植API中。正如您所说,“boost :: thread是...关于可移植性”。这是支持boost拥有“设置线程名称”方法的论点。 - Arthur Tacca

4
我正在使用Boost 1.50.0在Win32 + VS2010上,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 中获取数字?哎呀。 - David
抱歉,我不知道它是怎么发生的,现在应该已经完成了。至于线程数 - 我不知道。Boost文档说根本没有办法... - Odin
你可以通过传递 GetThreadId(在 <Windows.h> 中)本机句柄来获取线程 ID,该句柄可以从 boost 线程中获取。从那里,你可以执行 RaiseException 操作。不过 GetThreadId 更现代化,我想你无法在 XP 上运行。如果无法使用 GetThreadId,则还有一种方法可以从 boost::thread:id 中获取私有的 unsigned int,但那真的很邪恶。 - David
是的,正如所说的 - 使用 native_handle 和 GetThreadId,我得到了一个数字,它并不对应于应用程序的线程ID(尽管它是一个有效的系统线程ID)。因此对我来说,这种方法并不起作用。 - Odin
我的意思是,获得的 threadID 指向的是一个现有的线程,而不是由我的应用程序创建的线程。 - Odin

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接