C++: _beginthreadex, имя функции потока не отображается в окне потоков Visual Studio
Я недавно узнал, что ::_beginthreadex()
всегда предпочтительнее ::CreateThread()
, поэтому я изменил все мои звонки, которые использовали ::CreateThread()
,
Единственным недостатком является то, что я больше не вижу имя функции потока в Visual Studio Threads
Окно, затрудняющее быструю идентификацию потоков. Я предполагаю, что это было как-то сделано автоматически отладчиком, когда я использовал ::CreateThread()
Поскольку параметры в точности совпадают, я просто изменил название используемой функции.
Есть ли способ продолжать использовать ::_beginthreadex()
и увидеть имя потока в Threads
окно Visual Studio?
2 ответа
Это происходит потому, что _beginthreadex()
звонки CreateThread()
со своей собственной функцией потока, которая вызывает указанную вами (поэтому отладчик использует _threadstartex
имя функции - тот, который _beginthreadex()
вызывает).
Вы можете вручную установить имя потока, используя SetThreadName()
пример из MSDN. Что вы можете сделать, это создать свою собственную обертку для _beginthreadex()
это может выглядеть примерно так:
uintptr_t startthreadex(
void* security,
unsigned stacksize,
unsigned (__stdcall * threadproc) (void *),
void* args,
unsigned flags,
unsigned * pThread_id,
char* thread_name)
{
unsigned alt_thread_id;
if (!pThread_id) {
pThread_id = & alt_thread_id;
}
uintptr_t result = _beginthreadex(security, stacksize, threadproc, args, flgas, pThread_id);
if (result == 0) return result;
SetThreadName( *pThread_id, thread_name);
}
Теперь вы можете позвонить startthreadex()
вместо _beginthreadex()
и передать это имя потока. Небольшое преимущество заключается в том, что если вы используете одну и ту же функцию для запуска нескольких потоков, вы можете легко присвоить им уникальные имена, отражающие параметры, передаваемые из потока или что-то еще.
Если вы хотите, чтобы имя потока автоматически принималось за имя потока отладчика в качестве имени потока отладчика, вы можете создать макрос-обертку, который структурирует параметр имени функции (все, что требуется, - это другой уровень косвенности или для решения любой проблемы)..).
Вот SetThreadName()
(это от http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx):
//
// Usage: SetThreadName (-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, char* threadName)
{
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)
{
}
}
Там нет особого преимущества с использованием _beginthreadex
над CreateThread
, Функции CRT в конечном итоге вызовут CreateThread
только.
Вы должны прочитать: