4

我有线程 A 正在创建另一个线程 B,而不是线程 A 正在等待使用 WaitForSingleObject 等待线程 B 死亡。

问题是即使线程 B 从线程的“thread_func”返回,线程 A也没有收到信号!.

我知道,因为我在 thread_func(线程 B 的主函数)的末尾添加了跟踪(OutputDebugString),我可以看到线程 B 完成了它的执行,但线程 A 永远不会从 WaitForSingleObject 中出来。

现在,我还必须补充一点,这段代码在 COM 对象中,并且在我调用 regsvr32.exe 时会发生上述情况(它卡住了!),所以我相信线程 A 来自 DLLMain。

任何想法为什么线程 A 没有收到信号?!?!

4

2 回答 2

14

您可能遇到了加载程序锁的问题。Windows 有一个内部临界区,每当加载/卸载 DLL 或启动/停止线程时(始终在该锁内调用 DllMain),该临界区就会被锁定。如果您的等待线程 A 已锁定该临界区(即您在 DllMain 的某处等待),而另一个线程 B 尝试关闭并尝试获取该加载程序临界区,那么您就有了死锁。

要查看死锁发生的位置,只需从 VS IDE 调试器运行您的应用程序,然后在它卡住后中断执行。然后查看所有正在运行的线程,并注意每个线程的堆栈。您应该能够跟踪每个堆栈并查看每个线程正在等待什么。

于 2011-07-24T19:18:53.953 回答
4

我认为@DXM 是对的。关于你能做什么或不能做什么的文档DllMain很少而且很难找到,但最重要的是你通常应该将它保持在最低限度——初始化内部变量等,但仅此而已。

我要说的另一点是,您通常不应该调用” regsvr32.exe - 永远。

RegSvr32 基本上只是一个包装器,它将 DLL 加载到其地址空间中LoadLibrary,调用GetProcAddress以获取名为 的函数的地址DllRegisterServer,然后调用该函数。自己完成这项工作要干净得多(最终也更容易),如下所示:

HMODULE mod = LoadLibrary(your_COM_file); 
register_DLL = GetProcAddress(mod, "DllRegisterServer"); 
if ( register_DLL == NULL) { 
        // must not really be a COM object... 
} 

if ( S_OK != register_DLL()) { 
        // registration failed. 
} 
于 2011-07-24T19:47:09.543 回答