【发布时间】:2012-05-04 00:11:42
【问题描述】:
我的延迟加载 DLL 中有一个实例(全局/静态对象)ClassA。这个对象里面有一个“观察者”线程,它是执行正常关闭所必需的。当我调用 FreeLibrary 时,我注意到在删除此静态对象期间,我的线程请求关闭,但挂在 _endthreadex() 上并导致死锁。我是显式还是隐式调用 _endthreadex 都没有关系。对象是全局的还是静态的都没关系——结果相同。 该线程包裹在 ClassB 中(由带有自定义消息循环的模板实现)。有一个关闭线程的请求(发布消息)并跟随 WaitForSingleObject,它永远不会返回给定的线程句柄。
在代码中随处使用的相同“模板线程类”和关机效果很好。删除静态 obj 时的唯一问题。我认为 _endthreadex() 内部有一些锁,它在 dll 卸载和删除静态对象时已经被锁定。
线程以 _beginthreadex 开始。 附言。当我在 App 内部实例化相同的静态 obj 时 - 应用关闭时没有任何重大问题。
知道为什么 _endtreadex 会导致死锁吗?如何避免?
【问题讨论】:
-
来自 DllMAin 的文档 - 因为 DLL 通知是序列化的,所以入口点函数不应尝试与其他线程或进程通信。结果可能会发生死锁。 通常,在 DLL 终止期间您不能做很多事情。
-
死锁往往很容易诊断,您可以花时间使用 Debug + Break All 闯入调试器。查看线程的堆栈跟踪可以提供重要的线索。请务必启用调试符号服务器。
-
@dave 谢谢。这就解释了我得到了什么......
标签: c++ windows multithreading deadlock