スレッドベース

1857 ワード

スレッドにはスレッド関数が必要です.
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
    DWORD dwResult = 0;
    ...
    return(dwResult);
}

そして中で独立したプログラムとして書きます
次に、CreateThread関数を使用してスレッドを作成する方法を見てみましょう.まず、関数のプロトタイプを見てみましょう.
HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpsa,
    DWORD cbStack,
    LPTHREAD_START_ROUTINE lpStartAddr,
    LPVOID lpvThreadParam,
    DWORD fdwCreate,
    LPDWORD lpIDThread
);
  • 最初は旧友のセキュリティ記述子で、一般的にNULLを伝えるもの
  • スレッドスタックがどれだけのアドレス空間で伝送できるかを指定する2番目のスレッド0デフォルトは、この関数を呼び出すスレッドと同じ
  • である.
  • 第3の指定スレッド関数のアドレス
  • の4番目とスレッド関数に渡されたpvParamは同じ
  • です.
  • 5 5番目の5番目の0は、スレッドがすぐにCREATE_にスケジューリングできることを示しています.SUSPENDEDは、スレッドが初期化後に一時停止することを示し、ResumeThreadを使用してリカバリできます.
    STACK_にするとSIZE_PARAM_IS_A_RESERVATIONは、2番目のパラメータが利用可能であることを示す(だからこれでない場合はパラメータ2は0でなければならない)6番目がスレッドIDであることを示す必要がなければNULLは私たちがこれを必要としないことを示す

  • ExitThreadという関数については、C/C++のリソースは自動的に破棄されないので、スレッドが自動的に戻るのと同じようにTerminateThreadがあるのが望ましい.スレッドを指定できるのはもちろん使わないほうがいいです
    スレッドの具体的な実装メカニズムについて:まずCreateThread関数の呼び出しによってスレッドカーネルオブジェクトが作成されます2スレッドが終了しハンドルが閉じたときにのみスレッドカーネルオブジェクトが破棄され、他のプロパティが初期化されます:一時停止カウント1終了コードはSTILL_ACTIVE(0 x 103)オブジェクトが非トリガ状態に設定されると、プロセスのアドレス空間からスレッドにメモリが割り当てられ、次にスタックの最上端に2つの値が書き込まれる:LPVOID lpvThreadParam LPTHREAD_START_ROUTINE lpStartAddr、つまり前にCreateThreadに渡された2つのパラメータ
    プロセスごとに独自のCPUレジスタのセットがスレッドと呼ばれるコンテキスト(context)は、スレッドが前回実行されたときのCPU状態を反映しています.これらのレジスタはすべて1つのCONTEXT構造(WinNT.h)に保存されています.この構造自体はスレッドカーネルオブジェクトに保存されています.
    ESPとEIPは最も重要なESPメモリであるlpStartAddrのアドレスEIPは関数RtlUserThreadStartのアドレスである
    VOID RtlUserThreadStart(PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam)
    {
        __try {
            ExitThread((pfnStartAddr)(pvParam));
        }
        __except((UnhandledExceptionFilter(GetExceptionInformation()))) {
            ExitProcess(GetExceptionCode());
        }
    }