2009-05-25 40 views
15

どのようにしてWin32スレッドに名前を設定しますか?私は同じ目的を達成するためにWin32 APIを見つけませんでした。基本的には、ログファイルにスレッド名を追加します。 TLS(スレッドローカルストレージ)はそれを行う唯一の方法ですか?名前をWin32スレッドに設定する方法は?

+0

SetThreadDescription()APIがある:あなたがそのようなWinDbgを、Visual Studioの、およびクラッシュダンプファイルのように、このゲインより良いサポートを、ご覧になりたい方

、このリンクを使用して、それのために投票してくださいマイクロソフトがこれをサポートするためのAPIです詳細については、この回答を参照してください:http://stackoverflow.com/a/43787005/434413 –

答えて

1

この情報は、常に適切なデータ構造で保存することができます。 GetThreadId()をこの名前にマップするには、ハッシュまたはマップを使用します。 GetThreadId()は常に一意の識別子なので、これはうまくいきます。

乾杯!もちろん

彼は多くの スレッドを作成いた場合、そのハッシュマップは、ゆっくりとそう いくつかのクリーンアップ手順は、同様に、おそらく 良いことである、アップ を記入し、より多くのメモリを使用します。

あなたは絶対に正しいです。スレッドが消滅すると、マップ内の対応するエントリは必然的に削除されます。

+0

もちろん、彼が多くのスレッドを作成している場合、そのハッシュマップはゆっくりといっぱいになってメモリが使用されるため、クリーンアップの手順はおそらく良いことです。 –

+0

downvoting私もこの質問への回答が必要ですが、実際にプロファイリングの理由からスレッドに名前を設定する必要があります。あなたの答えは質問された質問に答えません:P –

29

これは役に立ちますか? How to: Set a Thread Name in Native Code

マネージコードでは、対応するThreadオブジェクトのNameプロパティを設定するのと同じくらい簡単です。

+1

私は、スレッド名を表示するVisual Studioのデバッガのためだけだと思います。 – Canopus

+1

他のデバッガは同じ信号に従っており、同じ信号に応答しています –

+3

http://thetweaker.wordpress.com/2009/04/10/naming-threads/ notesのように、スレッド名はデバッガのデータ構造。 Ergo、デバッガなしでは、名前は格納されず、ロギングの目的では使用できません。不快なバグもあります:デバッグしようとすると突然再び動作します。 – MSalters

1

デバッガ(windbgのまたはVisual Studio)であなたのスレッドの名前を表示したい場合は、次の http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx

私は実際にはよく分からないスレッド名を取得する逆の方法があるかどう。しかし、TLSは行く道のように聞こえる。

+0

あなたは間違った印象を持っています。スレッドの名前は**スレッドに保存されていません**。これはデバッガにのみ格納されるため、デバッガが接続されている場合にのみ存在します。デバッガがなければ、例外は単に何も起こっていないように続く次の例外フィルタに実行されます。アプリケーションがデバッガで実行されていない場合、スレッド名は失われます。 – 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

デバッガでコードを実行しない限り、これは機能しません。実際のシステムでスレッドの名前を記録するのに使用することはできません。 – IInspectable

9

のWin32スレッドには名前がありません。アプリケーションがスレッド名を含む特別なSEH例外を発生させるというMicrosoftの規則があります。これらの例外は、デバッガによって傍受され、スレッド名を示すために使用されます。答えのカップルはそれをカバーしています。

しかし、これはすべてデバッガで処理されます。スレッド自体は名前のないオブジェクトです。したがって、名前をスレッドに関連付ける場合は、独自のメカニズムを開発する必要があります。そのスレッドで実行されているコードからのみ名前を取得できるようにするスレッドローカルストレージを使用することができます。したがって、スレッドIDと名前の間のグローバルマップは、最も自然で有用なアプローチのように見えます。

1

これを行う別の方法は、スレッドのTEBのArbitraryUserPointerフィールドに名前へのポインタを格納することです。これは、実行時に読み書きすることができます。

"Debugging With The Thread Information Block"というコードプロジェクトの記事があります。

3

スレッドローカルストレージオブジェクトを使用して名前を格納できます。たとえば、

__declspec(thread) char threadName[32]; 

次に、スレッドからこれを読み書きできます。これは、すべてのメッセージのスレッド名を出力するロガーアプリケーションで役立ちます。スレッドが開始されるとすぐにこの変数を記述し、デバッガもスレッド名を知るようにMicrosoft例外(https://stackoverflow.com/a/10364541/364818)をスローしたいと思うかもしれません。

2

SetThreadDescription APIは、マイクロソフトのデバッグチームのリード(詳しくは下記のリンクを参照)によると、ネイティブコードで正式にスレッドの命名をサポートするためにMicrosoftによって使用されるAPIです。 「公式に」とは、現在、プロセスがVisual Studioで動作している間にのみ動作する現在の例外処理ハッキングとは対照的に、スレッドに名前を付けるためのMSサポートAPIを意味します。

このAPIは、Windows 10以降で利用可能になった、バージョン1607

は現在、しかし、非常に小さなツールのサポートがありますので、設定した名前は、Visual StudioまたはWinDbgのデバッガでは表示されません。ただし、2017年4月現在、Microsoft xperf/WPAツールでサポートされています(このAPIを介して指定されたスレッドは、これらのツールに名前が正しく表示されます)。

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

+0

更新:Windowsパフォーマンスアナライザと今後のWinDbgビルドで、SetThreadDescriptionAPIで設定されたスレッド名の表示がサポートされるようになりました。 https://blogs.msdn.microsoft.com/windbg/2017/06/29/debugger-updates-in-the-16225-sdk-preview/ –

関連する問題