web-dev-qa-db-ja.com

再帰スレッドを安全に強制終了する最も効率的でクリーンな方法

ビットマップのさまざまな領域でフラッドフィルタスクをすべて実行する多くのワーカースレッドがあります。それらはすべて、異なるパラメーター(座標)を使用して再帰的なサブルーチンを呼び出します。フィー、私はスキャンライン法を使っています。これらのプロセスを強制終了して再起動できるようにするリセット機能を実装しました。

私の殺害メカニズムを現在実装している方法は、手動リセットで殺害イベントを使用し、フラッドフィルサブルーチンが通知された場合はそれを返すようにすることです。このようにして、スレッドは境界線上にあるかなりの数のポイントを訪問しますが、あきらめてあきらめる前に、関連する塗りつぶし操作をスキップします。これを行うためのより効率的な方法があるかと思っていました。

追伸はい、私はそれがフラッドフィルのための過剰殺しであることを知っています、しかしこれは一般的な質問です。いくつかのローカル条件に基づいて高価なローカル操作を実行し、スキャンラインアプローチと同じ性質の再帰ルーチンを使用するマトリックスを想像できます。

編集:私のフレームワークの現在のデザインは次のとおりです:

m_pThread[i] = AfxBeginThread(FloodFill_Sub_ThreadProc, (LPVOID)m_pFloodFillInput[i], 0, 0, CREATE_SUSPENDED);

次のように定義されたスレッド手順:

UINT CTestShellDlg::FloodFill_Sub_ThreadProc(LPVOID pData)
{
...
FloodFill_Sub(mid, mid, Color_old, Color_new);
}

そして最後にFloodFill_Sub:

void CTestShellDlg::FloodFill_Sub(CPoint& node, CPoint& mid, COLORREF Color_old, COLORREF Color_new) /*Sub-routine to be used by threads*/
{
if (KillEventTriggered())
        return;
if (RecursionTerminationCondition)
        return;
//loop some scans and make recursive calls to FloodFill_Sub
...
}

ループセクションでは、さらにKillEventTriggered()チェックを追加できますが、もっと良いアプローチがあるかどうか疑問に思っています。

3
Maths noob

スレッドをすばやく効率的に「強制終了」するクリーンで安全な方法はありません。終了する必要があることをスレッドオブジェクトに通知できますが、スレッドは次のように記述する必要がありますこれを確認してからクリーンアップします。それ以外の場合は、部分的に終了する可能性があります-完了した操作、メモリリーク、リソースリーク、デッドロック、およびプログラム内のあらゆる種類のカオス。

関係するスレッドが再帰的な操作を実行していてサブスレッドを生成しているかどうかは、この基本原則を変更するものではありません。

5
Mason Wheeler