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 только.

Вы должны прочитать:

Другие вопросы по тегам