Как установить имя для Win32 Thread? - PullRequest
17 голосов
/ 25 мая 2009

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

Ответы [ 9 ]

31 голосов
/ 25 мая 2009

Это помогает? Как: установить имя потока в собственном коде

В управляемом коде это так же просто, как установить свойство Name соответствующего объекта Thread.

20 голосов
/ 28 апреля 2012

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)
  {
  }
}
10 голосов
/ 24 апреля 2013

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

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

4 голосов
/ 22 апреля 2015

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

__declspec( thread ) char threadName[32];

Тогда вы можете написать и прочитать это из ветки. Это может быть полезно в приложении для ведения журнала, где вы хотите распечатать название потока для каждого сообщения. Вы, вероятно, захотите записать эту переменную, как только поток начнется, а также выбросить исключение Microsoft (https://stackoverflow.com/a/10364541/364818), чтобы отладчик также знал имя потока.

3 голосов
/ 04 мая 2017

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

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

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

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

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

1 голос
/ 06 августа 2014

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

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

1 голос
/ 25 мая 2009

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

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

0 голосов
/ 25 августа 2018

Если ваше приложение работает в Windows версии 1607+, вы можете использовать SetThreadDescription ()

0 голосов
/ 25 мая 2009

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

Ура!

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...