3

疑似コードが次のようなスレッド関数を含む DLL があります。

volatile BOOL stopped = FALSE;

void StopEverything()
{
    /* Enter critical section */
    stopped = TRUE;
    /* Leave critical section */
}

void workerThreadFunc()
{
    Initialize();

    /* Checkpoint 1 */
    if(stopped)
    {
        /* Do cleanup */
        return;
    }

    doLaboriousTask1();

    /* Checkpoint 2 */
    if(stopped)
    {
        /* Do cleanup */
        return;
    }

    doLaboriousTask2();

    Uninitialize();
}

この DLL を使用するコードでは、クリーンアップ関数は次のようになります。

void cleanup()
{
    StopEverything();

    /* Wait for all threads to exit */
    /* Do other cleanup */
}

私の質問は 2 つあります。

  1. workerThreadFunc()さまざまなチェックポイントでそのようなチェックを行う代わりに、実行を停止するより良い方法はありますか?
  2. メインアプリケーションが を呼び出したときにworkerThreadFunc()がスタックしたとします。中断してすぐに終了させる方法はありますか?doLaboriousTask2()StopEverything() doLaboriousTask2()

ありがとう!

4

1 に答える 1

2

さまざまなチェックポイントでそのようなチェックを行う代わりに、workerThreadFunc() の実行を停止するより良い方法はありますか?

おそらくそうではありません。アンマネージ コードでスレッドをプリエンプティブに停止する、完全に信頼できる方法はありません。につながると主張するものは何でもTerminateThread。そして、ドキュメントには、その機能を使用した場合のあらゆる種類の悲惨な結果がリストされています。例えば:

  • ターゲット スレッドがクリティカル セクションを所有している場合、クリティカル セクションは解放されません。
  • ターゲット スレッドがヒープからメモリを割り当てている場合、ヒープ ロックは解放されません。
  • ターゲット スレッドが終了時に特定の kernel32 呼び出しを実行している場合、スレッドのプロセスの kernel32 状態が矛盾する可能性があります。
  • ターゲット スレッドが共有 DLL のグローバル状態を操作している場合、DLL の状態が破壊され、DLL の他のユーザーに影響を与える可能性があります。

あなたが尋ねる:

doLaboriousTask2() を中断してすぐに終了させる方法はありますか?

電話をかけることはできますTerminateThreadが、ドキュメントに記載されているすべての理由から、ほとんどの場合、それを行うべきではありません。

于 2013-03-21T10:36:48.593 に答える