c++ builder XE4, 10.2 Tokyo | TThread > スレッド名をコードでつける > SetThreadName(L"ThreadTest_tpNormal", threadID);


動作環境
C++ Builder XE4 on Windows 7 pro
Rad Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)

http://qiita.com/7of9/items/bfe8f229862c5b868699
の続き。

TThread のExecute() において以下の処理をすればスレッドの名前が付くことを発見した。

(追記 2016/03/06)

SetThreadName()はIndy10で用意されている関数のようだ。IdGlobal.pasに含まれる。
この関数を使う場合、Indy10関連のヘッダインクルードが必要になる。Indy10関連をincludeすると将来の移植時に問題が出る気がする。

それでも使用する場合は、Code Completeの「Identify Areas Likely to Change」に基づき、将来変更する部分を識別しやすくしておくのが望ましい。

#include <IdGlobal.hpp>
...
DWORD tid = GetCurrentThreadId();
SetThreadName(L"ThreadMain", tid);

スレッドの状態は以下のようになる。

IDEの「名前付きスレッド」機能を素直に使うのが楽かもしれないが、以前、「名前無し」スレッドから「名前付き」スレッドに変換しようとして「はまった」経験があるので上記のような方法としている。

v0.2

スレッドの優先度も記載すると他のスレッドとの関係性が明確になりデバッグしやすくなる。

#include <IdGlobal.hpp>
...
DWORD tid = GetCurrentThreadId();
SetThreadName(L"ThreadMain_tpNormal", tid);

v0.3

this->Priorityからスレッドの優先度を自動付加するコードを追加。

static String getThreadPriorityString(TThreadPriority priority)
{
    switch(priority) {
    case tpHigher:
        return L"_Higher";
    case tpNormal:
        return L"_tpNormal";
    case tpLower:
        return L"_tpLower";
    case tpLowest:
        return L"_tpLowest";
    case tpIdle:
        return L"_tpIdle";
    default:
        return L"_tpOther";
    }
}

以下のように使う。

#include <IdGlobal.hpp>
...
void __fastcall TThreadMain::Execute()
{
    // スレッド名の表示
    DWORD tid = GetCurrentThreadId();
    String thrnam = L"ThreadMain" + getThreadPriorityString(this->Priority);
    SetThreadName(thrnam, tid);

v0.4

UtilDebugThreadInfo.cpp, .hというファイルにスレッド名付加処理を移した。
クラスのstatic関数として実装。

それぞれのTThreadでは以下のように使う。

#include <UtilDebugThreadInfo.h>
...
void __fastcall TThreadMain::Execute()
{
    CUtilDebugThreadInfo::SetDebugInfoThreadName(this->Priority, L"ThreadMain");
        ...

TFormの場合は、Priorityというプロパティはなかったので、FormShowにて以下のようにする。
tpNormalは任意の値。

フォームで行うと、色々なフォームをShowするたびに、1つのスレッドの名前がころころ変わるようだ。

    CUtilDebugThreadInfo::SetDebugInfoThreadName(tpNormal, L"TMainForm");

UtilDebugThreadInfo.cppにまとめておくことで、将来の移植時にIndy10の関数シグネチャが変化したり、Indy10を使わなくなったりした場合にもこのファイルの修正で済む。
「Identify Areas Likely to Change.」というように変更(すべき)箇所のidentifyもしやすいはず。