我有一個在 WIN32 上運行的多執行緒應用程式,它使用信號量來保護鏈表。偶爾會出現這種情況。當它鎖定時,我可以cppvsdbg在 Visual Studio Code 下停止應用程式,我可以看到兩個執行緒正在等待信號量,即它們被阻塞在:
WaitForSingleObject(handle, INFINITE);
但是,第三個執行緒在這里被阻塞:
ReleaseSemaphore(handle, 1, NULL);
...即它似乎已經阻塞了ReleaseSemaphore(),這個功能當然會允許其他兩個執行緒之一運行。如果我在除錯器中單步執行,或者在呼叫之后設定一個斷點ReleaseSemaphore()并繼續運行,則沒有任何變化,應用程式仍處于鎖定狀態。被阻塞的執行緒ReleaseSemaphore()以優先級 0 運行,其他兩個執行緒以優先級 0 和 -1 運行,所以我看不出執行緒優先級如何導致問題。
不僅如此,我不明白為什么ReleaseSemaphore()在任何情況下都會阻止。的值handle是 0x000000ec,這是一天開始時的值,所以值handle沒有被破壞,盡管我猜可能是內容可能handle以某種方式搞砸了......?不知道我將如何除錯。
有沒有人對為什么會鎖定有任何建議ReleaseSemaphore(),或者當問題發生以確定發生了什么時,我可能會在除錯器中戳什么額外的東西?
編輯:代碼被編譯/Od以避免視覺除錯和代碼之間的任何錯位,這是cppvsdbg視窗顯示的似乎被阻止的執行緒的螢屏截圖ReleaseSemaphore():

uj5u.com熱心網友回復:
正確答案是:不,Win32 API 函式ReleaseSemaphore()永遠不會阻塞。
在這種情況下它出現阻塞的原因是,我們需要單獨模擬 Windows 上的關鍵部分(回想一下,此代碼通常在 RTOS 上的嵌入式系統中運行,Windows 僅用于快速開發)。為了模擬 Windows 上的關鍵部分,我們在除當前執行緒之外的所有執行緒上呼叫SuspendThread()(以及稍后)。當這樣一個模擬的關鍵部分就位時,代碼的其他地方ResumeThread()發生了故障,而且恰好這與呼叫大部分時間相吻合,使它看起來好像被阻塞了;它沒有,執行緒只是碰巧在那里暫停。ReleaseSemaphore()ReleaseSemaphore()
所以我們只需要修復另一個錯誤,這個明顯的問題就消失了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/457395.html
