3

私は、2 つのプロセスを含むプロジェクトに取り組んでいます。それらを A と B とします。A には、T1 と T2 の 2 つのスレッドがあります。

A と B は別々に実行されます。

ある時点で、T1 はメッセージ (COM 呼び出し、検索要求) を B に送信します。B がデータを処理すると、結果 (これも COM 呼び出し、検索結果) を直接 T2 に送信して返します。T2 が B のデータを処理するまで、T1 をブロックする必要があります。これまでのところ、次のソリューションを使用しました。

初期化: searchSyncSempahore = ::CreateSemaphore(NULL, 0, 1, NULL);

T1:

B_handle->search(searchString);
::WaitForSingleObject(searchSyncSempahore, INFINITE);
// Use searchResult variable

T2:

searchResult = _some_data_from_B;
::ReleaseSemaphore(searchSyncSempahore, 1, NULL);

これはこれまでのところ機能します。B が非常に高速であるため、T1 が WaitForSingleObject 行に到達する前に T2 が ReleaseSemaphore を呼び出す場合でも機能します。

私の問題は、B がクラッシュしたらどうなるかということです。T1は永遠に待つだけです。タイムアウトを指定する必要がありますが、T2 が結果を受け取るときにタイムアウトが短すぎると、セマフォが台無しになり、次の検索が台無しになります。

では、T2 が呼び出されないことを考慮して、これら 2 つのスレッドを正しく同期するにはどうすればよいでしょうか (つまり、「検索の中止」を実装するにはどうすればよいでしょうか)。

4

2 に答える 2

3

可能な解決策は、Manual-Reset eventsを使用してこのような状況を処理するウォッチドッグスレッドを作成することです。したがって、ロジックは少し変更されます。ミューテックスを待つ代わりに、イベントを待つことができます。ウォッチドッグ スレッドは、スレッドが長時間スタックしているかどうかを確認し、それ自体でイベントを設定し、重大な状況が発生したことを示す追加のイベントを設定できます。つまり、この 3 番目のスレッドはウォッチドッグ タイマーとして機能します。

もう 1 つのバリアントは、その 3 番目のスレッドで条件変数を使用することです。したがって、条件変数の 1 つをキックするだけで、それを待っているスレッドが起動します。私はこのアプローチにあまり慣れていないことを認めなければなりません。

UPDATE : SignalObjectAndWait関数の使用を検討してください。この関数は、1 つのオブジェクトにシグナルを送り、別のオブジェクトを 1 回の操作として待機します。また、待機タイムアウトを設定することもできます。オブジェクトの状態が非シグナル状態であっても、間隔が経過すると関数は戻ります。

スレッド ウォッチドッグを使用するもう 1 つの利点は、ファイルや MS EventLog にログを記録したり、アプリケーションの動作を変更するロジックを提供したりできることです。もう 1 つの例は、ウォッチドッグ スレッドが「スレッドの冗長性」機能を実装できることです。

于 2012-06-14T10:14:35.320 に答える
2

明示的なウォッチドッグよりも簡単な方法は、プロセス ハンドルを待機することです。

Windows の待機関数は、ハンドルの種類 (ファイル、ソケット、スレッド、プロセス、イベントなど) のほとんどすべてを待機できます。

したがって、セマフォとプロセス ハンドル (またはメイン スレッド ハンドル) の両方WaitForMultipleObjectsを使用して、待機セットに入れます。セマフォが通知された場合、またはプロセスが終了した場合 (何らかの理由で)、待機関数はそれに応じて戻る必要があります。

戻り値から、待機関数が返されたオブジェクトを区別できます ( または のいずれかである必要がありますWAIT_OBJECT_0) WAIT_OBJECT_0 + 1待機関数を呼び出す前にクラッシュが既に発生している場合、ハンドルは無効です。その場合、待機関数は を返す必要がWAIT_FAILEDあるため、チェックする必要がある別の条件です。

于 2012-06-14T11:26:47.640 に答える