2008-11-21 83 views
1

我有一個線程,當它的函數退出其循環(退出由事件觸發)時,它會進行一些清理,然後設置一個不同的事件,讓主線程知道它已完成。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的博客),這是一件非常糟糕的事情。

問題在於,由於它被編碼的方式和它的行爲方式,這並不是顯而易見的,這是潛在的問題 - 它被僞裝成我必須涉及的各種其他不良行爲。

這裏的一些建議幫助我做到了這一點,所以我很感謝所有貢獻的人。謝謝!

+0

不工作難.... :-) – Asher 2008-11-21 23:53:54

回答

1

誰在卸載DLL並在什麼時候卸載完成?我想知道在線程運行完成之前DLL是否被卸載的時間問題。

2

你是不是把HANDLE *傳遞給SetEvent?事件句柄引用更可能是無效的,崩潰是訪問衝突(即訪問垃圾)。

0

您可能想使用WinDbg來捕捉崩潰並檢查堆棧。

0

爲什麼你需要在從屬線程中設置一個事件來觸發主線程完成線程?剛剛退出線程,調用主線程應該等待工作線程退出,例如僞碼 -

Master 
{ 
    TerminateEvent = CreateEvent (...) ; 
    ThreadHandle = BeginThread (Slave, (LPVOID) TerminateEvent) ; 
    ... 
    Do some work 
    ... 
    SetEvent (TerminateEvent) ; 
    WaitForSingleObject (ThreadHandle, SOME_TIME_OUT) ; 
    CloseHandle (TerminateEvent) ; 
    CloseHandle (ThreadHandle) ; 
} 

Slave (LPVOID ThreadParam) 
{ 
    TerminateEvent = (HANDLE) ThreadParam ; 
    while (WaitForSingleObject (TerminateEvent, SOME__SHORT_TIME_OUT) == WAIT_TIMEOUT) 
    { 
     ... 
     Do some work 
     ... 
    } 
} 

有很多的錯誤情況和狀態檢查,但是這是我怎麼通常做的精髓它。

如果你能掌握它,那麼得到這本書,它在很多年前第一次閱讀它時就改變了我對Windows開發的看法。

Advanced Windows: The Developer's Guide to the Win32 Api for Windows Nt 3.5 and Windows 95 (Paperback), by Jeffrey Richter (Author)

相關問題