Подтвердить что ты не робот

Как установить имя для потока Win32?

Как установить имя в поток Win32. Я не нашел Win32 API для достижения того же. В основном я хочу добавить имя потока в файл журнала. Является ли TLS (Thread Local Storage) единственным способом сделать это?

4b9b3361

Ответ 1

Вы всегда можете сохранить эту информацию для себя в подходящей структуре данных. Используйте хеш или карту, чтобы отобразить GetThreadId() для этого имени. Поскольку GetThreadId() всегда является уникальным идентификатором, это работает отлично.

Приветствия!

Конечно, если он создал много потоки, то hashmap будет медленно заполнять и использовать все больше и больше памяти, поэтому некоторые процедуры очистки, вероятно, являются хорошая вещь также.

Ты абсолютно прав. Когда нить умирает, ее соответствующая запись на карте, естественно, должна быть удалена.

Ответ 3

http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.90).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)
  {
  }
}

Ответ 4

В потоках Win32 нет имен. Существует соглашение Microsoft, в котором приложения генерируют специальные исключения SEH, содержащие имя потока. Эти исключения могут быть перехвачены отладчиками и использованы для указания имени потока. Об этом говорят несколько ответов.

Однако все это обрабатывается отладчиком. Нити сами по себе являются безымянными объектами. Итак, если вы хотите связать имена с вашими потоками, вам придется разработать свой собственный механизм. Хотя вы можете использовать локальное хранилище потоков, которое позволит вам получить имя из кода, выполняемого в этом потоке. Таким образом, глобальная карта между идентификатором потока и именем будет выглядеть как наиболее естественный и полезный подход.

Ответ 5

Вы можете использовать объект локального хранилища потоков для хранения имени. Например,

__declspec( thread ) char threadName[32];

Затем вы можете написать и прочитать это из потока. Это может быть полезно в приложении регистрации, где вы хотите распечатать имя потока для каждого сообщения. Вероятно, вы захотите записать эту переменную сразу после запуска потока, а также выбросить исключение Microsoft (fooobar.com/questions/299927/...), чтобы отладчик также знал имя потока.

Ответ 6

В соответствии с обсуждением с руководством группы отладки Microsoft (см. ссылку ниже для подробностей) API SetThreadDescription - это API, который будет использоваться Microsoft в будущем для поддержки именования потоков в собственном коде. Под "официально" я подразумеваю API, поддерживающий MS, для именования потоков, в отличие от текущего взлома исключения, который в настоящее время работает только в процессе работы Visual Studio.

Этот API стал доступен начиная с Windows 10, версии 1607.

В настоящее время, однако, очень мало поддержки инструментов, поэтому указанные вами имена не будут видны в отладчиках Visual Studio или WinDbg. Однако с апреля 2017 года инструменты Microsoft xperf/WPA поддерживают его (потоки, названные через этот API, будут правильно отображаться в этих инструментах).

Если вы хотите, чтобы это улучшало поддержку, например, в файлах WinDbg, Visual Studio и crash dump, проголосуйте за него, используя эту ссылку:

https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/17608120-properly-support-native-thread-naming-via-the-sett

Ответ 7

Если вы хотите увидеть название своего потока в отладчике (windbg или visual studio):   http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx

Я не уверен, есть ли обратный метод для получения имени потока. Но TLS звучит как способ пойти.

Ответ 8

Другой способ сделать это - сохранить указатель на имя в поле ArbitraryUserPointer TEB потока. Это можно записать и прочитать во время выполнения.

Здесь есть статья CodeProject под названием "Отладка с помощью информационного блока" , в которой показано, как это сделать.