1

マルチスレッドアプリケーションがあります。ワーカー スレッドの 1 つは、ログ記録のために GetModuleFilename を呼び出します。GetModuleFilename を呼び出す前にワーカー スレッドがロックを保持し、永久にブロックするデッドロックが発生しました。

このロック内から GetModuleFilename 呼び出しを削除することはできますし、削除しましたが、デッドロックがどのように発生するかについてはまだ非常に関心があります。

オンラインで読書をする: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx

GetModuleFilename がローダーロックを取得するようです。これは、デッドロックのかなり良い候補のように思えました。

ただし、通常、ローダーロック内のスレッドは、上記のリンクのように dllmain を除いて、独自のコードを実行していません。

dll_thread_attach または detach は、ローダーロックと、作成または破棄される別のワーカースレッドで呼び出される可能性がありますが、これが使用しているロックを取得しようとする方法はわかりません。

また、メイン スレッドが GetModuleFilename スレッドが保持しているロックを取得しようとし、3 番目のスレッドがローダーロックを保持し、sendmessage などをメイン スレッドでブロックしている可能性もあります。ここでも、これが発生する状況は見つかりませんでした。

私が疑わしい他のスレッドの 1 つは、com オブジェクトを使用するスレッドです。スレッドは最初に coinitialize を呼び出すため、シングル スレッド アパートメントにする必要があります。ここでローダーロックと相互作用する可能性はありますか?

とにかく、このデッドロックが発生する正確な方法を特定できていません。だから私はいくつかのアイデア、またはローダーロックが取得されている他のケースに関する詳細情報、およびブロックされる可能性のあるローダーロック内でコードが実行される他のシナリオがあるかどうかを期待しています。

ありがとう。

4

2 に答える 2

0

さて、私が説明した問題は、私たちが使用したライブラリの別の問題の症状に過ぎないことが判明しました。ライブラリは明らかに 2 つの異なるスレッドでいくつかの wininet API を使用しており、そのうちの 1 つは dllmain とローダーロック内にありました。これら 2 つのスレッドがデッドロックし、その後、GetModuleFileName を呼び出したスレッドがロックされました。

今のところ私が知っているのはこれくらいですが、ライブラリのベンダーから詳細が戻ってきたら、これを更新します.

于 2012-07-19T21:50:38.247 に答える
0

いくつかのランダムなアイデア:

  • C++ (C だけでなく) コードがある場合、システムがロード ロックを保持している間に、DLL で静的に割り当てられたオブジェクトのコンストラクターも実行される可能性があります。そのようなオブジェクトのコンストラクタ/デストラクタでロックをどこでも使用していませんか?

  • おそらく、ロックにもかかわらずバグが存在する可能性があり、ロックを使用すると、たとえば、スレッドでアクションのタイミングを変更するなどして、実際にはレースを「再表示」するだけかもしれません。DllMain()スレッドは扱いにくい場合があります。http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspxを参照してください。

于 2012-06-22T22:46:16.443 に答える