6

我的延迟加载 DLL 中有一个实例(全局/静态对象)ClassA。这个对象里面有一个“观察者”线程,它是执行正常关闭所必需的。当我调用 FreeLibrary 时,我注意到在删除此静态对象期间,我的线程请求关闭,但挂在 _endthreadex() 上并导致死锁。我是显式还是隐式调用 _endthreadex 都没有关系。对象是全局的还是静态的都没关系——结果相同。该线程包裹在 ClassB 中(由带有自定义消息循环的模板实现)。有一个关闭线程的请求(发布消息)并跟随 WaitForSingleObject,它永远不会为给定的线程句柄返回。

代码中随处使用的相同“模板线程类”和关闭效果很好。删除静态 obj 时的唯一问题。我认为 _endthreadex() 内部有一些锁,它在 dll 卸载和删除静态对象时已经被锁定。

线程以 _beginthreadex 开头。附言。当我在 App 内实例化相同的静态 obj 时 - 应用程序关闭时没有任何重大问题。

任何想法为什么 _endtreadex 会导致死锁?如何避免?

4

1 回答 1

8

这种特殊情况很容易解释。_endthreadex 调用需要加载程序锁,以便它可以使用 DLL_THREAD_DETACH 调用 DllMain。但是,调用 FreeLibrary 的线程已经持有加载程序锁,因为您已经在使用 DLL_PROCESS_DETACH 调用 DllMain。

另一种可能中断的方式是,如果进程在没有显式卸载库的情况下退出,您的观察者线程将在调用 DLL_PROCESS_DETACH之前终止,因此当您尝试发出退出信号时,它不会响应,因为它没有运行不再。

最好的方法可能是创建显式 InitializeLibrary() 和 UninitializeLibrary() 函数供用户调用。

于 2012-05-04T02:28:06.740 回答