多方面理解臨界區的使用:
轉載:http://blog.csdn.net/amwfnyq/article/details/25139067
偶然發現Windows API函數LeaveCriticalSection存在一個問題,那就是在調用它離開臨界區時,會把臨界區引用計數減一,而不判斷當前線程是不是擁有該臨界區,這樣就可能引發問題,比如A線程擁有該臨界區,但B線程可以調用LeaveCriticalSection來使得其它等待該臨界區的線程擁有該臨界區,或者調用LeaveCriticalSection次數大於EnterCriticalSection的次數也可能出現誤操作而導致不可預知的後果。
把EnterCriticalSection換下面這一段代碼可以有效的防止佔用鎖的線程已經退出而導致死鎖的情況(親測有效):
//嘗試進入臨界區
while(!TryEnterCriticalSection(&moSection)){
//進入失敗,判斷當前佔有臨界區的線程是否還存活
if(aoSection.RecursionCount > 0){
DWORD result = WaitForSingleObject(aoSection.OwningThread, 0);
if(result == WAIT_FAILED){
//如果線程已經退出,則代表線程被異常結束或代碼問題導致鎖沒有釋放,就利用此bug強制釋放鎖
while(aoSection.RecursionCount > 0){
LeaveCriticalSection(&moSection);
}
}
}
}
一篇文章,每次閱讀都會有新的認知!