2013-02-20 11 views
9

(WaitForSingleObject/ReleaseMutex呼び出しを使用して)同じmutexを共有する2つのプロセス(A、B)があります。すべてうまく動作しますが、プロセスAがクラッシュすると、プロセスBはうまくハミングしています。プロセスAを再起動すると、デッドロックが発生します。Win32プロセスがクラッシュしたときに名前付きミューテックスが解放されない

深い調査では、プロセスAがクラッシュした後、プロセスBがReleaseMutex()を2回正常に呼び出すことができます。

私の解釈:プロセスAがクラッシュした後でも、ミューテックスはロックされていますが、ミューテックスの所有権はプロセスB(バグ)に容易に移ります。 WaitForSingleObject(WAIT_OBJECT_0を取得)とReleaseMutex(TRUEを返す)を呼び出すことで、うれしいことにハミングアップするのです。

プロセスAのクラッシュがミューテックスを解放するような方法で、Mutexに似た名前付き同期プリミティブを使用できますか?

解決策の1つは、SEHを使用してクラッシュを捕捉してミューテックスを解放することですが、Windowsにはプロセスクラッシュのようなデッドロックのない堅牢なプリミティブがあることを願っています。

+2

これはあなたが読める面白い記事です:http://blogs.msdn.com/b/oldnewthing/archive/2005/09/12/463977.aspx –

答えて

24

あなたはミューテックスは、Windows上でどのように機能するかについては、ここで確認する必要がありますいくつかの基本的な仮定:

  • ミューテックスは、参照カウントのオペレーティングシステムオブジェクトです。これは、参照カウント
  • ミューテックスがWaitForSingleObject関数を呼び出し、再入でデクリメント、ミューテックスの最後のハンドルが閉じられるまでのプロセスが終了したときに閉じられていない残って
  • 任意のハンドルがオペレーティングシステムによって閉鎖されて消えることはありません同じスレッド上のミューテックス上で成功し、同数のReleaseMutexコールで均衡する必要があります。
  • 所有しているmutexがになりました。所有しているスレッドがReleaseMutexを呼び出さずに終了した場合。この状態のミューテックスでWaitForSingleObjectを呼び出すと、WAIT_ABANDONEDエラーが返されます。戻りコード
  • これは決してオペレーティングシステムのバグではありません。

あなたが観察したことによって結論を引き出すことができます。 Aがクラッシュしたときにミューテックスに何も起こりません。Bにはまだハンドルがあります。唯一の可能な方法は、Aがミューテックスを所有しているときにAがクラッシュしたときにAがクラッシュしたことに気付くことができます。これは非常に低い確率であり、Bはデッドロックになるので容易に観測されます。 Bが今では完全に妨げられていないので、Bは喜んでモーターオフになります。誰もミューテックスをもう取得しないでしょう。

さらに、Aがバックを開始したときのデッドロックは、あなたがすでに知っていたことを証明します。Bは何らかの理由でミューテックスを永久に所有しています。 mutexを再帰的に取得した可能性があります。あなたは、あなたがReleaseMutexを2回呼び出さなければならないことに気づいたので、これを知っています。これは修正する必要があるバグです。

あなたはクラッシュする兄弟プロセスから身を守る必要があり、そのための明示的なコードを書く必要があります。兄弟のOpenProcessを呼び出して、プロセスオブジェクトのハンドルを取得します。プロセスの終了時にハンドル上のWaitForSingleObject呼び出しが完了します。

+4

+1 "これは決してオペレーティングシステムのバグではありません。" :p – Deanna

+0

申し訳ありませんが、私はこれを答えとしてフラグを立てていませんでした。 ありがとう、私は放棄された状態の意味を知らなかった。 –

9

ミューテックスを保持するプロセスがクラッシュすると、そのプロセスは破棄されます。待機関数から返されるこの状態を処理する方法は、他のアプリケーションに任されます。

WAIT_ABANDONEDが返ってきたら、すべてがOKだったか(おそらく現在の状況)、または「潜在的に不安定なデータの場合は注意して進んでください。 所有権は自動的に別のプロセスに渡されません。

+10

私の推測では、プロセスBは「WAIT_ABANDONEDミューテックスをもう一度取得しようとするので、「予期しない方法で成功した」よりも「WAIT_FAILED」を意味すると考えます。 –

関連する問題