私はサポートエンジニアとして働いていますが、失敗したプロセスのダンプで、いくつかのロックがあることがわかります。
Windbgの使用(Visual Studioは呼び出しスタックを正しく処理できません)1つの関数(ClassName::F()
)が戻ってきていることがわかりました。その関数はクリティカルセクションを使用しClassName::f_sub()
、同じクリティカルセクションを呼び出しているサブ関数()を簡単に呼び出します。
int ClassName::f_sub(){
EnterCriticalSection(&m_cs);
...
LeaveCriticalSection(&m_cs);
return ...;
}
int ClassName::F() {
EnterCriticalSection(&m_cs);
...
int temp = f_sub();
...
LeaveCriticalSection(&m_cs);
return ...;
}
毎回、同じクリティカルセクションm_cs
(のプロパティClassName
)が使用されています。
私の意見では、これにより次のシーケンスが可能になります。
Thread 1 : F() : Enter the critical section. (Thread 1 is in)
Thread 1 : f_sub() : Enter the critical section. (Thread 1 is in)
Thread 1 : f_sub() : Leave the critical section. (Thread 1 is out)
Thread 2 : F() : Enter the critical section. (Thread 2 is in)
=> WRONG! Thread 2 should be forced to wait for Thread 1 leaving the critical section via F().
私の分析は正しいですか?これは、メイン機能とサブ機能に異なるクリティカルセクションを設けることをお勧めすることを意味しますか?
私の分析は正しいですか?これは、メイン機能とサブ機能に異なるクリティカルセクションを設けることをお勧めすることを意味しますか?
以下からのMicrosoftドキュメント(強調鉱山):
スレッドがクリティカルセクションの所有権を取得した後、その実行をブロックすることなく、EnterCriticalSectionまたはTryEnterCriticalSectionを追加で呼び出すことができます。これにより、スレッドがすでに所有しているクリティカルセクションを待機しているときに、スレッドがデッドロックするのを防ぎます。EnterCriticalSectionとTryEnterCriticalSectionが成功するたびに、スレッドはクリティカルセクションに入ります。スレッドは、クリティカルセクションに入るたびにLeaveCriticalSectionを1回呼び出す必要があります。
いいえ、あなたが説明したことは起こらないはずです。クリティカルセクションに何度も入るのはまったく問題ありませんし、正確に何回も出る必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加