2009-05-25 10 views
15

Wie setze ich einen Namen zu einem Win32-Thread. Ich habe keine Win32-API gefunden, um dasselbe zu erreichen. Grundsätzlich möchte ich den Thread-Namen in der Log-Datei hinzufügen. Ist TLS (Thread Local Storage) der einzige Weg, dies zu tun?Wie setze ich einen Namen auf einen Win32-Thread?

+0

Die SetThreadDescription() API ist , vorwärts, die API, mit der Microsoft dies unterstützen wird. Weitere Informationen finden Sie in dieser Antwort: http://stackoverflow.com/a/43787005/434413 –

Antwort

1

Diese Informationen können Sie jederzeit in einer geeigneten Datenstruktur speichern. Verwenden Sie einen Hash oder eine Map, um GetThreadId() diesem Namen zuzuordnen. Da GetThreadId() immer ein eindeutiger Bezeichner ist, funktioniert das problemlos.

Prost!

Natürlich, wenn er viele Fäden zu schaffen ist, wird dieser hashmap langsam up füllen und mehr und mehr Speicherplatz, so einige Bereinigungsverfahren sind wahrscheinlich eine gute Sache auch.

Sie haben absolut Recht. Wenn ein Thread stirbt, sollte der entsprechende Eintrag in der Map natürlich entfernt werden.

+0

Natürlich, wenn er viele Threads erstellt, wird diese hashmap langsam füllen und mehr und mehr Speicher verwenden, so dass einige Cleanup-Prozedur ist wahrscheinlich auch eine gute Sache. –

+0

downvoting, weil ich auch eine Antwort auf diese Frage brauche, aber ich muss tatsächlich einen Namen für die Profilerstellung Gründe für den Thread festlegen. Ihre Antwort beantwortet die gestellte Frage nicht: P –

29

Hilft das? How to: Set a Thread Name in Native Code

In verwaltetem Code ist es so einfach wie das Festlegen der Name-Eigenschaft des entsprechenden Thread-Objekts.

+1

Ich denke, es ist nur für den Visual Studio-Debugger den Thread-Namen anzuzeigen. – Canopus

+1

Andere Debugger sind dem Beispiel gefolgt und reagieren auf dasselbe Signal –

+3

Wie alle http://thetweaker.wordpress.com/2009/04/10/naming-threads/ Notizen speichern, indem sie den Thread-Namen in einer Debugger-Datenstruktur speichern . Ergo, ohne einen Debugger würde der Name nicht gespeichert und wäre nicht für Protokollierungszwecke verfügbar. Nasty Bug auch: Wenn Sie versuchen, es zu debuggen, funktioniert es plötzlich wieder. – MSalters

1

Wenn Sie den Namen des Threads im Debugger (windbg oder Visual Studio) sehen mag: http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx

Ich bin nicht wirklich sicher, ob es eine Reverse-Methode ist die Thread-Namen zu erhalten. Aber TLS klingt wie der Weg zu gehen.

+0

Sie haben den falschen Eindruck. Der Name des Threads wird ** nicht ** mit dem Thread gespeichert. Es wird nur im Debugger gespeichert und ist daher nur vorhanden, wenn ein Debugger angeschlossen ist. Ohne einen Debugger läuft die Exception einfach auf den folgenden Ausnahmefilter, der so weitergeht wie nie zuvor. Der Thread-Name ist verloren, wenn die Anwendung nicht unter einem Debugger ausgeführt wird. – IInspectable

17

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) 
    { 
    } 
} 
+0

Dies funktioniert nicht, es sei denn, Sie führen den Code unter einem Debugger aus. Es kann sicherlich nicht verwendet werden, um den Namen eines Threads in einem Live-System zu protokollieren. – IInspectable

9

Win32-Threads haben keine Namen. Es gibt eine Microsoft-Konvention, bei der Anwendungen spezielle SEH-Exceptions auslösen, die einen Thread-Namen enthalten. Diese Ausnahmen können von Debuggern abgefangen und zur Angabe des Thread-Namens verwendet werden. Ein paar Antworten decken das ab.

Das wird jedoch alles vom Debugger behandelt. Threads selbst sind namenlose Objekte. Wenn Sie also Ihren Threads Namen zuweisen möchten, müssen Sie einen eigenen Mechanismus entwickeln. Sie können zwar lokalen Threadspeicher verwenden, mit dem Sie jedoch nur den Namen aus dem Code abrufen können, der in diesem Thread ausgeführt wird. Eine globale Karte zwischen der Thread-ID und dem Namen erscheint also als der natürlichste und nützlichste Ansatz.

1

Eine andere Möglichkeit besteht darin, einen Zeiger auf den Namen im Feld ArbitraryUserPointer des TEB des Threads zu speichern. Dies kann zur Laufzeit geschrieben und gelesen werden.

Es gibt einen CodeProject-Artikel mit dem Titel "Debugging With The Thread Information Block", der Ihnen zeigt, wie Sie das tun.

3

Sie können ein Thread-lokales Speicherobjekt zum Speichern des Namens verwenden. Zum Beispiel

__declspec(thread) char threadName[32]; 

Dann können Sie dies aus einem Thread schreiben und lesen. Dies kann in einer Logger-Anwendung nützlich sein, in der Sie den Namen des Threads für jede Nachricht ausdrucken möchten. Wahrscheinlich möchten Sie diese Variable schreiben, sobald der Thread gestartet wird, und außerdem die Microsoft-Ausnahme (https://stackoverflow.com/a/10364541/364818) auslösen, damit der Debugger auch den Namen des Threads kennt.

2

Gemäß der Diskussion mit dem Microsoft-Debugging-Team (siehe untenstehenden Link für Details) ist die API SetThreadDescription, die von Microsoft verwendet wird, um die Thread-Benennung offiziell in systemeigenem Code zu unterstützen. Mit "offiziell" meine ich eine MS-unterstützte API für die Benennung von Threads, im Gegensatz zu dem aktuellen Ausnahme-werfenden Hack, der derzeit nur funktioniert, während ein Prozess in Visual Studio ausgeführt wird.

Diese API wurde in Windows 10 verfügbaren Ausgang, Version 1607.

Derzeit gibt es jedoch nur sehr wenig Tooling-Unterstützung, so dass die Namen, die Sie festgelegt werden nicht in dem Visual Studio oder WinDbg Debugger sichtbar sein. Ab April 2017 unterstützen jedoch die Microsoft xperf/WPA-Tools (über diese API benannte Threads werden in diesen Tools ordnungsgemäß angezeigt).

Wenn Sie diese Verstärkung eine bessere Unterstützung sehen möchten, wie in WinDbg, Visual Studio, und Crash-Dump-Dateien, wählen Sie bitte für es über diesen Link:

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

+0

Update: Windows Performance Analyzer und ein anstehender Build von WinDbg unterstützen jetzt das Anzeigen der über SetThreadDescriptionAPI festgelegten Thread-Namen. https://blogs.msdn.microsoft.com/windbg/2017/06/29/debugger-updates-in-the-16225-sdk-preview/ –

Verwandte Themen