std ::线程 – 命名您的线程

新的C ++有这个std ::线程types。 奇迹般有效。 现在我想给每个线程一个更简单的debugging名称(如Java允许您)。 用pthreads我会做:

pthread_setname_np(pthread_self(), "thread_name"); 

但我怎样才能做到这一点与C ++ 0x? 我知道它在Linux系统下使用pthreads,但我想使我的应用程序可移植。 有没有可能?

一个可移植的方法是维护一个由thread::get_id()获得的线程ID的键名的映射。 或者,如注释thread_local ,如果您只需要从线程内访问名称,则可以使用thread_localvariables。

如果你不需要可移植性,那么你可以从thread::native_handle()得到底层的pthread_t ,并用它来做任何你喜欢的平台特定的thread::native_handle() 。 请注意,线程命名函数上的_np表示“not posix”,所以它们不能保证在所有的pthreads实现上都可用。

试图制作一个包装器来处理许多Linux和Windows。 请根据需要进行编辑。

 #ifdef _WIN32 #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(uint32_t dwThreadID, const char* threadName) { // DWORD dwThreadID = ::GetThreadId( static_cast<HANDLE>( t.native_handle() ) ); 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) { } } void SetThreadName( const char* threadName) { SetThreadName(GetCurrentThreadId(),threadName); } void SetThreadName( std::thread* thread, const char* threadName) { DWORD threadId = ::GetThreadId( static_cast<HANDLE>( thread->native_handle() ) ); SetThreadName(threadId,threadName); } #else void SetThreadName(std::thread* thread, const char* threadName) { auto handle = thread->native_handle(); pthread_setname_np(handle,threadName); } #include <sys/prctl.h> void SetThreadName( const char* threadName) { prctl(PR_SET_NAME,threadName,0,0,0); } #endif 

你可以使用std::thread::native_handle获得底层实现定义的线程。 这本来就没有标准的function。

你可以在这里find一个例子。

对于windows [debugger],你可以很容易的使用“normal”方法; http://msdn.microsoft.com/en-gb/library/xcb2z8hs.aspx

只需要你可以获得的线程ID

 #include <windows.h> DWORD ThreadId = ::GetThreadId( static_cast<HANDLE>( mThread.native_handle() ) ); 

我已经看到这个系统在c ++ 11之前完成(我们基本上发明了自己的Thread类,它和std :: thread非常相似),最近我写了一个。

基本上,池真的把std :: thread 2层放下 – 你有一个PoolThread类,它包含一个std :: thread,加上它的名字,ID等元数据以及将它连接到控制池的控制结构, ThreadPool本身。 您想在大多数线程代码中使用线程池有几个原因:
1)你可以隐藏所有显式的“分离”,“join”,从std :: thread构造开始线程等。 这产生了更安全,更干净的代码。
2)更好的资源pipe理:太多的线程会比性能下降更多。 一个精心打造的游泳池可以做高级的事情,如自动负载平衡和清理挂起或死锁的线程。
3)线程重用:std ::线程本身最容易使用通过在自己的线程上运行每个并行任务。 但是线程的创build和销毁是很昂贵的,如果你不小心的话,可以很容易地从并行处理中缓解速度的提升。 所以,通常情况下更有意义的是有一个池线程将工作任务从队列中拉出来,只有在接收到某个信号后才退出。
4)error handling:std :: thread只是一个执行上下文。 如果你正在运行的任务抛出一个未处理的exception或者std :: thread ITSELF失败,那么这个进程就会在那里崩溃。 要做容错multithreading,你需要一个Pool或类似的东西,可以快速捕捉这些东西,至less在进程死亡之前发出有意义的错误消息。