看來,當一個線程是從DllMain在DLL_PROCESS_ATTACH
上創建的,它將不會開始,直到所有的dll被加載完畢。由於我需要確保線程在我繼續之前運行,所以我會陷入僵局。有什麼辦法強制線程啓動?在DllMain中創建線程?
回答
你不應該做任何的API調用,特別是對於一些像自的DLLMain創建線程或窗口。 Raymond Chen已經寫了很多次了,這裏的one特別相關。
不可以。您不應該從DllMain調用CreateThread(或任何變量)。嘗試同步會導致死鎖。你究竟想要做什麼?
調用CreateThread沒什麼不妥,但是沒有辦法解決這個問題,直到在父線程中完成DllMain處理之後線程纔會被掛起。 – 2010-02-06 18:32:28
如果你這樣做,你就會遇到麻煩。你不應該直接或間接地調用你的dll之外的函數(包括C庫調用等)。
如果你不能改變你有的DLL(例如你沒有源代碼),你可能會得到如果你的DLL動態加載後,其他依賴的DLL是初始化。如果你可以避免它,我不會推薦這種方法,因爲找出依賴鏈並不總是微不足道的(例如,如果你的dll導致依賴dll通過COM或其他方式動態加載第三個)。
這裏的第一段是過度泛化。對你知道的DLL進行調用是完全正確的,因爲事實已經在你之前加載了。一般情況下,在大多數情況下,這隻意味着KERNEL32.DLL,這聽起來像是一個嚴重的限制,但你可以用它來引導你擺脫這種情況。 – 2010-04-20 16:08:28
http://blogs.msdn.com/oldnewthing/archive/2007/09/04/4731478.aspx – 2010-04-20 16:33:24
感謝Integer詩人。這正好回答了我來這裏解決的問題。 – 2010-05-05 23:42:23
你的線程是做什麼的?
如果您嘗試將內容移動到第二個線程以避免限制您在DllMain中可以執行的操作,那就太難過了。這些並不限制DllMain可以執行的操作,它們限制了DllMain運行時(並保持加載器鎖定)可以執行的操作。如果你的線程需要加載器鎖,它將等待,直到第一個線程完成使用它。如果你的線程不需要加載器鎖,我不明白爲什麼它不能立即繼續下去......但是不存在不需要加載器鎖的線程。 Windows必須在您的線程開始運行之前將DLL_THREAD_ATTACH消息發送給所有DLL,這意味着它也會調用您自己的DllMain,並且Windows可以防止再次入侵。
有沒有辦法解決這個問題。直到DLL_THREAD_ATTACH處理後,線程才能啓動,並且在第一個線程位於DllMain內時不會發生。唯一可行的方法是開始一個新的進程(它有一個獨立的加載程序鎖定,不會阻止等待你的)。
在處理DLL_PROCESS_ATTACH消息期間,我嘗試了一個在'DLLMain()'中使用'CreateThread()'作爲一個非常簡單的工作函數的簡單練習。線程函數使用'Sleep()'1000毫秒。一切正常。我可以看到來自執行'DLL_PROCESS_ATTACH'的初始線程和附加處理期間創建的線程的'DLL_THREAD_ATTACH'消息和'DLL_THREAD_DETACH'消息。然而這個工作線程除了睡眠()之外什麼也沒做。 Kernel32.dll調用應該沒問題。經過VS 2005 Windows 7測試。 – 2016-02-21 18:39:24
奇怪的是,這真的是解決問題的唯一答案。我不知道爲什麼OP決定接受一個不是的答案。 – IInspectable 2016-05-04 20:04:02
- 1. 如何在C#中創建DLLMain
- 2. 在線程中創建PDF
- 3. 在Titanium中創建線程
- 4. 在DLL中創建線程
- 5. 在C#中創建線程
- 6. 在Java中創建線程
- 7. 在Rxjava中創建線程
- 8. 在python中創建線程
- 9. 在Win32中創建線程
- 10. 創建線程
- 11. 線程創建
- 12. 線程創建
- 13. 無法在創建2700個線程後創建本地線程
- 14. Log4Net在主線程中工作,但不在創建線程中
- 15. dllmain中的DLL_THREAD_ATTACH期間暫停其他線程
- 16. 在Python中創建線程中的線程
- 17. 在C++中創建線程時出錯
- 18. 如何在main()中創建線程
- 19. 在XS中創建線程回調
- 20. 在中間創建Jmeter線程
- 21. 在新窗口中創建線程C++
- 22. Xstream沒有在線程中創建
- 23. 如何在haskell中創建線程?
- 24. 在python中創建許多線程?
- 25. 如何在Kotlin中創建線程池
- 26. 在JavaFX中創建和停止線程
- 27. 在Windows 8.1中創建線程
- 28. 在Azure Web角色中創建線程
- 29. 在c中創建線程池#
- 30. Tkinter:cannnot在線程中創建消息框
CreateThread是您可以在DllMain中執行的少數幾件事之一,因爲它是對kernel32的調用,保證已經加載。 – 2010-02-06 18:24:53
@Ben Voigt,但要非常小心,因爲如果要求當前的DllMain調用等待新線程返回,很容易死鎖。 – mloskot 2010-11-09 13:43:20
@mloskot:無論你在等待什麼樣的對象,在DllMain中調用等待函數都很糟糕。通常,任何執行DLL代碼的線程都需要在該DLL上引用計數,而不是從代碼下面映射出代碼。這可以防止問題發生,因爲只要線程正在運行,DllMain就不會被調用(用於進程分離)。 – 2010-11-09 14:06:11