CThreadの停止




あるスレッド(CThreadによるスレッド)を他のスレッドが停止させるには、3つの方法があります。

まずひとつ目.

枠-1
    CThread::InvalidateThread


を呼び出す。このメソッドを呼び出すと、そのスレッドの

枠-2
    bool    IsThreadValid()

は、falseを返すようになります。

つまり、ワーカースレッド側は、

list-1
    while(IsThreadValid()){
        //  ここに何かの処理を書く
    }


と書いてあるものとします。そうすれば、他スレッドからInvalidateThreadが呼び出されれば、いずれwhileから抜けるというものです。(処理が長引けば、すぐに抜けるとは限りません)

yaneSDK3rdで、ゲームプログラムを行なう場合は、毎フレーム画面更新を行なうことを前提とすることが多いので、このスタイルで書いてもかまいません。

ただし、見てのとおり、InvalidateThreadを行なったところで、すぐにスレッドが停止するとは限りません。

2.CThread::StopThread

このメソッドを(他のスレッドから)呼び出せば、そのスレッドはInvalidateされ、そのあと、停止を待って、そして制御を返します。すなわち、StopThreadから戻ってきたときには、そのスレッドは停止していることが保証されます。

3.CThread::interruptを呼び出す

interruptメソッドを呼び出すと、そのスレッドは割り込み状態になります。
しかし、すぐに停止するわけではありません。次にCThread::waitかsleepを呼び出したときに、割り込み状態になっていれば、CInterruptedException例外を投げます。あるいは、wait実行中、sleep実行中に他スレッドがCThread::interruptを呼び出せば、その瞬間、そのスレッドはCInterruptedException例外を投げます。

逆に言えば、wait/sleepを行なわない限り、CInterruptedException例外は投げられないので、ときどき次のメソッドを呼び出して、調べる必要があります。

枠-3
    virtual bool    interrupted();
    /// 割り込み状態になっているかを返すが、その後、
    /// 割り込み状態はリセットする。


このメソッドは、

list-2
    if (interrupted()) {
        throw CInterruptedException();
    }


というように、使います。割り込み状態は、このメソッド呼び出し後にリセットされることに注意してください。つまり、上のプログラムは、「割り込み状態」を「割り込み例外」というように、「状態」を「例外」へ変換したと解釈できます。

逆に、「例外」を「状態」へ変換することも出来ます。

list-3
    try {
        hoge_function();
    } catch (CInterruptedException& e){
        interrupt();
    }


また、割り込み状態になっているかどうかをチェックすることも出来ます。

枠-4
    virtual bool    isInterrupted() const;
    /// 割り込み状態になっているか


こちらは、割り込み状態のリセットは行ないません。interruptedとisInterruptedとは名前が紛らわしいので気をつけましょう。(このへんはJavaのスレッドとある程度互換性がありますので、わかりにくい点はJavaのスレッド関係について調べてみると良いかも知れません)