Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有线程句柄的WaitForSingleObject在运行regsvr32.exe时卡住_C++_Multithreading_Winapi_Synchronization_Waitforsingleobject - Fatal编程技术网

C++ 具有线程句柄的WaitForSingleObject在运行regsvr32.exe时卡住

C++ 具有线程句柄的WaitForSingleObject在运行regsvr32.exe时卡住,c++,multithreading,winapi,synchronization,waitforsingleobject,C++,Multithreading,Winapi,Synchronization,Waitforsingleobject,我有一个线程A正在创建另一个线程B,而线程A正在使用WaitForSingleObject等待线程B死亡 问题是,即使线程B从线程的“thread_func”返回,线程A也不会收到信号 我知道这是因为我在线程_func(线程B的主函数)的末尾添加了跟踪(OutputDebugString),并且我可以看到线程B完成了它的执行,但是线程A从未从WaitForSingleObject中出来 现在,我还必须补充一点,这段代码位于COM对象中,上面描述的场景发生在我调用regsvr32.exe时(它卡住

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

问题是,即使线程B从线程的“thread_func”返回,线程A也不会收到信号

我知道这是因为我在线程_func(线程B的主函数)的末尾添加了跟踪(OutputDebugString),并且我可以看到线程B完成了它的执行,但是线程A从未从WaitForSingleObject中出来

现在,我还必须补充一点,这段代码位于COM对象中,上面描述的场景发生在我调用regsvr32.exe时(它卡住了!),因此我相信线程a来自DLLMain


知道为什么线程A没有得到信号吗

装载机锁可能有问题。Windows有一个内部关键部分,每当加载/卸载DLL或启动/停止线程时,该部分都会被锁定(在该锁内始终调用DllMain)。如果正在等待的线程A锁定了该关键部分(即,您正在从DllMain等待),而另一个线程B尝试关闭并尝试获取该加载程序关键部分,则会出现死锁


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

我认为@DXM是正确的。关于在
DllMain
中可以做什么或不能做什么的文档非常稀少,很难找到,但底线是,通常应该将其保持在最低限度——初始化内部变量等等,仅此而已

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

RegSvr32基本上只是一个包装器,它使用
LoadLibrary
将DLL加载到其地址空间,调用
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. 
} 

你完全正确!!!我不知道它是这样工作的!所以我想我将使用另一个事件来通知结束线程B线程。在这个答案上为+1。让DllMain调用任何非平凡的代码路径(包括进行系统和API调用的代码)只是自找麻烦。很抱歉,我不明白为什么
regsvr32
不好,为什么很早就编写自己的代码。您不知道创建整个过程,只调用一个函数有什么问题吗?这里我们有四行代码可以工作。您要使用的
system
代码至少应该有三行,而且还不起作用——到您使它起作用的时候,代码会多得多(两行代码都比您的多,四行代码都比您的多——多得多)。我没有看到任何关于
system
的内容。最有可能的是OP从控制台窗口手动运行regsvr32.exe(就像我们中的许多人一样)来注册他的COM库,但由于系统锁定,它被卡住了。因此,我完全不明白仅仅为了注册这个COM库而实现额外的工具是如何有帮助的,甚至与这个问题有关。你的方法也会这么做,他的库也会一样