【发布时间】:2018-07-26 08:22:22
【问题描述】:
我知道我无法从 DllMain 创建线程,但是在 DLL 中创建线程的正确方法是什么?
我试图创建一个环绕它的类并声明该类的全局实例,但随后 WaitForSingleObject 挂在该类的析构函数中,即使我确定线程已退出。
这是我从 exe 加载 dll 的示例程序:
#include <Windows.h>
#include <iostream>
using namespace std;
int main(int argc, TCHAR* argv[])
{
HMODULE module = LoadLibraryA("dll.dll");
Sleep(500);
if (module) FreeModule(module);
else cout << "failed to load library...\n";
return 0;
}
这里是dll代码:
#include <Windows.h>
#include <iostream>
using namespace std;
class X
{
HANDLE thread = NULL;
static DWORD WINAPI run_thread(LPVOID param)
{
cout << "dll.cpp: thread started\n";
Sleep(1000);
cout << "dll.cpp: thread is exiting\n";
return 0;
}
public:
X()
{
DWORD tmp;
thread = CreateThread(NULL, 0, run_thread, NULL, 0, &tmp);
if (thread == NULL)
{
cout << "failed to create thread\n";
throw 1;
}
}
~X()
{
if (thread != NULL)
{
cout << "joining thread...\n";
DWORD ret = WaitForSingleObject(thread, INFINITE);
cout << "result from waiting: " << ret << "\n";
thread = NULL;
}
}
}x;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
cout << __FUNCTION__ << " reason DLL_PROCESS_ATTACH\n";
break;
case DLL_THREAD_ATTACH:
cout << __FUNCTION__ << " reason DLL_THREAD_ATTACH\n";
break;
case DLL_THREAD_DETACH:
cout << __FUNCTION__ << " reason DLL_THREAD_DETACH\n";
break;
case DLL_PROCESS_DETACH:
cout << __FUNCTION__ << " reason DLL_PROCESS_DETACH\n";
break;
}
return TRUE;
}
这是程序输出:
DllMain reason DLL_PROCESS_ATTACH
DllMain reason DLL_THREAD_ATTACH
dll.cpp: thread started
DllMain reason DLL_PROCESS_DETACH
joining thread...
dll.cpp: thread is exiting
<- notice how WaitForSingleObject hangs,
even though the thread has exited
这种方法有什么问题?
如果我碰巧从 run_thread 中删除了 Sleep(1000),以便线程在调用 WaitForSingleObject 之前完成,那么它不会挂起:
DllMain reason DLL_PROCESS_ATTACH
DllMain reason DLL_THREAD_ATTACH
dll.cpp: thread started
dll.cpp: thread is exiting
DllMain reason DLL_THREAD_DETACH
DllMain reason DLL_PROCESS_DETACH
joining thread...
result from waiting: 0
我不明白其中的区别,这也不是一种选择,因为线程的目的是在没有发出 DLL_PROCESS_DETACH 信号的情况下不断循环。
【问题讨论】:
-
程序调用 FreeModule() 而该模块中的代码仍在忙于执行。行为未定义。
标签: c++ windows multithreading dll