我在延迟加载的DLL中有一个实例(全局/静态对象)ClassA。这个对象里面有一个“Observer”线程,它是执行正常关闭所必需的。当我调用FreeLibrary时,我注意到在删除此静态对象期间,我的线程请求关闭但挂起_endthreadex()并导致死锁。如果我明确地或隐含地调用_endthreadex并不重要。对象是全局的还是静态的 - 无关紧要 - 结果相同。 此线程包含在ClassB中(由带有自定义消息循环的模板实现)。有一个请求关闭线程(post message)和WaitForSingleObject,它永远不会返回给定的线程helele。
相同的“模板线程类”在代码中使用,并且关闭效果很好。删除静态obj时唯一的问题。我认为_endthreadex()里面有一些锁已经锁定在dll卸载和删除静态对象上。
线程以_beginthreadex开头。 PS。当我在App-app内部实例化相同的静态obj时,关闭时没有任何重大问题。
为什么_endtreadex导致死锁的想法?如何避免呢?
答案 0 :(得分:5)
这个特例很容易解释。 _endthreadex调用需要加载器锁定,以便它可以使用DLL_THREAD_DETACH调用DllMain。但是,调用FreeLibrary的线程已经保存了加载程序锁,因为您已经在使用DLL_PROCESS_DETACH调用DllMain。
这可能会破坏的另一种方法是,如果进程在没有显式卸载库的情况下退出,那么您的观察者线程将在 DLL_PROCESS_DETACH调用之前终止,因此当您尝试发出信号退出时,它不会回应,因为它不再运行。
最好的方法可能是创建显式的InitializeLibrary()和UninitializeLibrary()函数供用户调用。