我有一個線程,當它的函數退出其循環(退出由事件觸發)時,它會進行一些清理,然後設置一個不同的事件,讓主線程知道它已完成。Windows:什麼情況下SetEvent()不會立即返回?
但是,在某些情況下,SetEvent()在設置線程的「我完成」事件後似乎不返回。
此線程是DLL的一部分,問題似乎發生在DLL已加載/附加,線程啓動,線程結束和DLL分離/卸載多次而沒有關閉應用程序之間的問題。在發生這個問題之前,這個序列必須被重複的次數是可變的。
如果您懷疑我知道我在說什麼,我已通過調用OutputDebugString()來調用SetEvent()調用來確定發生了什麼。出現SetEvent()之前的輸出。然後,等待線程產生表示事件已被設置的輸出。
但是,在退出線程(一個AFTER SetEvent())中第二次調用OutputDebugString()永遠不會發生,或者至少不會出現它的字符串。如果發生這種情況,應用程序會在一會兒之後崩潰。
(注意,要OutputDebugString的調用()後,問題開始出現加,所以它不太可能被掛在那裏,而不是在SetEvent的()。)
我不能完全確定是什麼原因引起的崩潰,但它發生在SetEvent()沒有立即返回的同一個線程中(我一直在跟蹤/輸出線程ID)。我想有可能SetEvent()最終會返回,到那時它返回的上下文已經失效/無效,但是什麼會導致這樣的延遲?
事實證明,我通過查看這段代碼已經失明瞭很長時間,甚至沒有發現我檢查返回代碼。我今天已經看完了,所以我會在星期一知道它返回的是什麼(,如果它正在返回),然後我將用該信息編輯此問題。
更新:我更改了(主)代碼以等待線程退出而不是它設置事件,並從從線程刪除了SetEvent()調用。這改變了錯誤的性質:現在,它不會無法從SetEvent()返回,它不會退出線程,整個事件都會掛起。
這表明問題不在SetEvent()中,而是深入一些。不知道是什麼,但是,不要追逐那條盲巷很好。
更新(09年2月13日):
事實證明,問題比我想的要深,當我問這個問題時。 jdigital(可能還有其他人)已經基本解決了底層問題:我們試圖卸載一個線程作爲分離DLL過程的一部分。
這個,因爲我當時並沒有意識到,但後來通過這裏和其他地方的研究發現(例如Raymond Chen的博客),這是一件非常糟糕的事情。
問題在於,由於它被編碼的方式和它的行爲方式,這並不是顯而易見的,這是潛在的問題 - 它被僞裝成我必須涉及的各種其他不良行爲。
這裏的一些建議幫助我做到了這一點,所以我很感謝所有貢獻的人。謝謝!
不工作難.... :-) – Asher 2008-11-21 23:53:54