DLL ExitInstance上的线程消失

Threads disappeared on DLL ExitInstance

本文关键字:线程 消失 ExitInstance DLL      更新时间:2023-10-16

我有一个windows DLL函数InitInstance和ExitInstance。DLL创建一些线程,带有_beginthreadx的工作线程和带有Message Queue的线程,源自CWinThread (MFC).

DLL应该可以被任何应用程序使用。

我为这个DLL写了一个小的主机应用程序来测试,它工作得很好,除了当我关闭这个主机应用程序没有调用FreeLibrary之前。在本例中是ExitInstance也调用,但是所有线程都消失了,这是非常不寻常的,并导致死锁作为一些例程等待线程完成,它不再存在-因为它是完成或杀死。我需要走这种方式(跳过调用FreeLibrary),以模拟可能发生的事情其他应用程序使用这个DLL。

ExitInstance被调用,但是所有的线程通常仍在运行的消失-很可能是因为DLL的处理方式不同

当从宿主进程中卸载时,如果你之前没有调用FreeLibrary

它们无声地消失,例如,如果一个线程只是在循环中使用WaitForSingleObject实现一个循环,那么这个线程不会正常结束。

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

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

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

CWinThread::ExitInstance的文档非常明确:"除了在Run成员函数中,不要从任何地方调用这个成员函数。"(即CWinThread::Run,线程本身)。

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

调用的是DllMain,但只有一次,并且带参数DLL_PROCESS_DETACH。你不会得到DLL_THREAD_DETACH,因为这发生在之后,你的线程干净地退出(即ExitInstance或从CWinThread::Run返回)。

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