退出线程在卸载DLL期间删除静态对象导致死锁? [英] Exit thread upon deleting static object during unload DLL causes deadlock?

查看:371
本文介绍了退出线程在卸载DLL期间删除静态对象导致死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实例(全局/静态对象)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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆