C ++: _beginthreadex, имя функции потока не отображается в окне потоков Visual Studio - PullRequest
1 голос
/ 18 августа 2011

Недавно я узнал, что ::_beginthreadex() всегда предпочтительнее ::CreateThread(), поэтому я изменил все свои вызовы, которые использовали ::CreateThread().

Единственным недостатком является то, что я больше не вижу имя функции потока в окне Threads Visual Studio, что затрудняет быструю идентификацию потоков. Я предполагаю, что это было каким-то образом сделано автоматически отладчиком, когда я использовал ::CreateThread(), поскольку параметры в точности совпадают, я просто изменил название используемой функции.

Есть ли способ продолжать использовать ::_beginthreadex() и видеть имя потока в окне Threads Visual Studio?

Ответы [ 2 ]

3 голосов
/ 18 августа 2011

Это происходит потому, что _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)
   {
   }
}
1 голос
/ 18 августа 2011

Нет особого преимущества при использовании _beginthreadex над CreateThread. Функции CRT в конечном итоге вызовут только CreateThread.

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

...