1

我有一个带有函数 InitInstance 和 ExitInstance 的 Windows DLL。DLL 创建一些线程,使用 _beginthreadex 的工作线程和使用消息队列的线程,从 CWinThread (MFC) 派生。

DLL 应该可供任何应用程序使用。

我为此 DLL 编写了一个小型主机应用程序进行测试,它工作正常,除非我关闭此主机应用程序而之前没有调用 FreeLibrary。在这种情况下,ExitInstance 也被调用,但所有线程都消失了,这是非常不寻常的,并导致死锁,因为一些例程等待一个不再存在的线程完成 - 因为它已完成或被杀死。我需要这样做(跳过调用 FreeLibrary)以模拟其他应用程序使用此 DLL 时可能发生的情况。

ExitInstance 被调用,但所有通常仍在运行的线程都消失了 - 很可能是因为如果您之前不调用 FreeLibrary,从主机进程卸载 DLL 时会以某种方式处理。

它们默默地消失,例如,如果一个线程只是在循环中实现了一个带有 WaitForSingleObject 的循环,则该线程不会正常完成。

thread()
{
    while(running == true)
    {
        WaitForSingleObject(...);
    }
    threadfinished=true; /// 1
}

如果在关闭应用程序之前调用 FreeLibrary,则调用代码部分 1。当关闭应用程序而不调用 FreeLibrary 时,代码部分 1 永远不会被调用,但循环也不再运行,因为线程被删除。

我应该如何处理这种情况?谢谢

4

1 回答 1

1

的文档CWinThread::ExitInstance非常清楚:“不要从任何地方调用这个成员函数,而是在Run成员函数内。” (即CWinThread::Run线程本身)。

显然,这意味着 Windows 不会ExitInstance为您打电话。主机应用程序也不是,因为它不知道您的线程。

所谓的是DllMain但只有一次和有论据DLL_PROCESS_DETACH。你不会得到DLL_THREAD_DETACH,因为这发生你的线程干净地退出(即ExitInstance或从返回CWinThread::Run)之后。

顺便说一下,请考虑在您的 DLL 被卸载后您的线程可以运行哪些代码。它不能是您的函数或 MFC,因为这些函数不再存在。线程将因访问冲突而崩溃,因为它的指令指针现在指向未分配的内存。

于 2013-04-05T16:03:46.913 回答