CAMThread クラス
CAMThread クラスは、ワーカー スレッドを管理する抽象クラスである。
要件
ヘッダー: Wxutil.h で宣言し、Streams.h をインクルードする。
ライブラリ: Strmbase.lib (リテール ビルド) または Strmbasd.lib (デバッグ ビルド)。
プロテクト メンバ変数 | |
m_hThread | スレッドのハンドル。 |
パブリック メンバ変数 | |
m_AccessLock | 他のスレッドからアクセスされないようにスレッドをロックするクリティカル セクション。 |
m_WorkerLock | スレッド間で共有されているデータをロックするクリティカル セクション。 |
パブリック メソッド | |
CAMThread | コンストラクタ メソッド。 |
~CAMThread | デストラクタ メソッド。仮想。 |
InitialThreadProc | スレッドが作成されたとき、ThreadProc メソッドを呼び出す。 |
Create | スレッドを作成する。 |
CallWorker | スレッドに要求を通知する。 |
Close | スレッドの終了を待ち、そのリソースを解放する。 |
ThreadExists | スレッドがあるかどうかを問い合わせる。 |
GetRequest | 次の要求を待つ。 |
CheckRequest | 要求がある場合は、ブロックせずにチェックする。 |
Reply | 要求に応答する。 |
GetRequestHandle | CallWorker メソッドで通知済みのイベントのハンドルを取得する。 |
GetRequestParam | 最新の要求を取得する。 |
CoInitializeHelper | スレッドの開始時に CoInitializeEx を呼び出す。 |
純粋仮想メソッド | |
ThreadProc | スレッド プロシージャ。 |
注意
このクラスはワーカー スレッドの作成、そのスレッドへの要求の送信、そのスレッドの終了待機のためのメソッドを提供する。このクラスの使い方は次のとおりである。
- CAMThread からクラスを派生させ、純粋仮想メソッド CAMThread::ThreadProc をオーバーライドする。このメソッドはスレッドの開始時に呼び出されるスレッド プロシージャである。
- アプリケーション内で、派生クラスのインスタンスを作成する。オブジェクトを作成してもスレッドは作成されない。スレッドを作成するには CAMThread::Create メソッドを呼び出す。
- スレッドに要求を送るには、CAMThread::CallWorker メソッドを呼び出す。このメソッドの DWORD パラメータの意味はクラスによって定義される。このメソッドはスレッドが応答するまでブロックする (次を参照)。
- スレッド プロシージャで、CAMThread::GetRequest または CAMThread::CheckRequest のどちらかを呼び出すことによって要求に応答する。GetRequest メソッドは他のスレッドが CallWorker を呼び出すまでブロックする。CheckRequest メソッドは非ブロッキング メソッドであるため、スレッドは非同期に動作している最中に新しい要求の有無をチェックできる。
- スレッドは要求を受け取ると、CAMThread::Reply を呼び出して要求元のスレッドをブロック解除する。Reply メソッドの DWORD パラメータは CallWorker の戻り値として要求元のスレッドに渡される。
スレッドでの処理が終了したら、CAMThread::Close メソッドを呼び出す。このメソッドはスレッドの終了を待機し、スレッド ハンドルを閉じる。ThreadProc メッセージは独自に、または CallWorker 要求への応答で終了することが保証されていなければならない。デストラクタ メソッドもまた Close を呼び出す。
次のサンプル コードは、これらのステップを示している。
class MyThread : public CAMThread
{
protected:
DWORD ThreadProc(void);
};
DWORD MyThread::ThreadProc()
{
BOOL bShutDown = FALSE;
while (!bShutDown)
{
DWORD req = GetRequest();
printf("Request: %d\n", req);
bShutDown = (req == 0);
Reply(bShutDown ? S_FALSE : S_OK);
}
printf("Quitting Thread\n");
return 1;
}
void main()
{
MyThread thread;
DWORD reply;
thread.Create();
reply = thread.CallWorker(3);
reply = thread.CallWorker(0); // スレッド終了。
}
派生したクラスで、CallWorker のパラメータを有効にするメンバ関数を定義することもできる。次のサンプル コードは、これを行う一般的な方法を示している。
enum Command {CMD_INIT, CMD_RUN, CMD_STOP, CMD_EXIT};
HRESULT Init(void) { return CallWorker(CMD_INIT); }
HRESULT Run(void) { return CallWorker(CMD_RUN); }
HRESULT Stop(void) { return CallWorker(CMD_STOP); }
HRESULT Exit(void) { return CallWorker(CMD_EXIT); }
CAMThread クラスはパブリック メンバ変数として 2 つのクリティカル セクションを提供する。CAMThread::m_AccessLock を使って、他のスレッドからアクセスされないようにスレッドをロックする。たとえば、Create と CallWorker メソッドはこのロックを保持し、スレッドの操作を継続する。CAMThread::m_WorkerLock を使い、スレッド間で共有されているデータをロックする。