退出线程在卸载DLL期间删除静态对象导致死锁? [英] Exit thread upon deleting static object during unload DLL causes deadlock?
问题描述
我有一个实例(全局/静态对象)ClassA在我的延迟加载的DLL。这个对象里面有一个观察者线程,需要执行正常关机。当我调用FreeLibrary我注意到,在删除此静态对象期间,我的线程请求关闭,但挂在_endthreadex()并导致死锁。没关系,如果我调用_endthreadex显式或隐式。无论对象是全局的还是静态的 - 结果相同。
此线程包装在ClassB中(通过带有自定义消息循环的模板实现)。有一个请求关闭线程(post消息)和以下WaitForSingleObject,它从不返回给定的线程heandle。
I have one instance (global/static object) ClassA inside of my delay-loaded DLL. This object inside has an "Observer" thread which is required to perform graceful shutdown. When I call FreeLibrary I noticed that during deletion of this static object my thread requested to shutdown but hangs on _endthreadex() and causes deadlock. It doesn't matter if I call _endthreadex explicitly or implicitly. It doesn't matter if object is global or static - same result. This thread wrapped in ClassB (implemented by template with custom message loop). There is a request to shutdown thread (post message) and following WaitForSingleObject which never returns for given thread heandle.
相同的模板线程类工作伟大。删除静态obj时的唯一问题。我想在_endthreadex()里面有一些锁,它已经锁定在dll卸载和删除静态对象上。
Same "template thread class" used everywhere in the code and shutdown works great. The only issue when deleting static obj. I think there is some lock inside of _endthreadex() which is already locked upon dll unload and deleting of static objects.
线程以_beginthreadex开头。
ps。当我实例化同一个静态obj里面的应用程序 - 应用程序关闭没有任何重大问题。
Thread started with _beginthreadex. ps. When I instantiated same static obj inside of App - app closes without any significant issues.
任何想法为什么_endtreadex导致死锁?如何避免?
Any ideas why _endtreadex causes deadlock? How to avoid it?
推荐答案
这种特殊情况很容易解释。 _endthreadex调用需要加载器锁,以便它可以用DLL_THREAD_DETACH调用DllMain。然而,调用FreeLibrary的线程已经拥有加载器锁,因为你已经在使用DLL_PROCESS_DETACH调用DllMain。
This particular case is easy to explain. The _endthreadex call needs the loader lock so that it can call DllMain with DLL_THREAD_DETACH. The thread that called FreeLibrary, however, already holds the loader lock, because you're already in the middle of a call to DllMain with DLL_PROCESS_DETACH.
另一种方法是break是,如果进程退出而没有显式卸载库,你的观察者线程将在 DLL_PROCESS_DETACH调用之前被终止,因此当你试图发出信号退出时,它将不会响应,因为它isn'
The other way this can break is that if the process exits without explicitly unloading the library, your observer thread will be terminated before the DLL_PROCESS_DETACH call, so when you try to signal it to exit, it won't respond because it isn't running any more.
最好的方法是创建显式的InitializeLibrary()和UninitializeLibrary()函数供用户调用。
The best approach is probably to create explicit InitializeLibrary() and UninitializeLibrary() functions for the user to call.
这篇关于退出线程在卸载DLL期间删除静态对象导致死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!