Multithreading 在DLL_DETACH中连接线程
我有一个被注入进程的DLL,当进程终止时,我希望在DLL卸载时终止线程 因此,我得出以下结论:Multithreading 在DLL_DETACH中连接线程,multithreading,c++11,winapi,dll,Multithreading,C++11,Winapi,Dll,我有一个被注入进程的DLL,当进程终止时,我希望在DLL卸载时终止线程 因此,我得出以下结论: // Wrapper around std::thread that notifies the task it should stop.. class TaskThread { private: std::mutex mutex; std::thread thread; std::atomic_bool stop; std::function<void()>
// Wrapper around std::thread that notifies the task it should stop..
class TaskThread {
private:
std::mutex mutex;
std::thread thread;
std::atomic_bool stop;
std::function<void()> onStop;
public:
TaskThread(std::function<void(TaskThread*)> &&task, std::function<void()> &&onStop);
~TaskThread();
bool stopped();
};
TaskThread::TaskThread(std::function<void(TaskThread*)> &&task, std::function<void()> &&onStop) : onStop(onStop)
{
this->thread = std::thread([this, task]{
task(this);
});
}
TaskThread::~TaskThread()
{
//set stop to true..
std::unique_lock<std::mutex> lock(this->mutex);
this->stop = true;
lock.unlock();
//signal the task
onStop();
//join the thread..
this->thread.join();
}
bool TaskThread::stopped()
{
std::unique_lock<std::mutex> lock(this->mutex);
bool stopped = this->stop;
lock.unlock();
return stopped;
}
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
static std::unique_ptr<TaskThread> task_thread;
static std::unique_ptr<Semaphore> semaphore;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hinstDLL);
semaphore.reset(new Semaphore(0));
task_thread.reset(new TaskThread([&](TaskThread* thread){
while(thread && !thread->stopped()) {
if (!semaphore)
{
return;
}
semaphore->wait();
if (!thread || thread->stopped())
{
return;
}
runTask(); //execute some function
}
}, [&]{
if (semaphore)
{
semaphore->signal();
}
}));
}
break;
case DLL_PROCESS_DETACH:
{
task_thread.reset(); //delete the thread.. triggering the destructor
}
break;
}
return TRUE;
}
//std::thread的包装器,通知任务它应该停止。。
类任务线程{
私人:
std::互斥互斥;
标准:螺纹;
标准:原子波停止;
std::函数在顶部;
公众:
TaskThread(std::function&&task,std::function&&onStop);
~taskshread();
布尔停止();
};
TaskThread::TaskThread(std::function&&task,std::function&&onStop):onStop(onStop)
{
this->thread=std::thread([this,task]{
任务(本);
});
}
TaskThread::~TaskThread()
{
//将stop设置为true。。
std::unique_lock锁(此->互斥锁);
此->停止=真;
lock.unlock();
//发出任务信号
顶部();
//加入线程。。
这个->线程.join();
}
bool TaskThread::stopped()
{
std::unique_lock锁(此->互斥锁);
bool stopped=此->停止;
lock.unlock();
返回停止;
}
BOOL APIENTY DllMain(HINSTANCE hinstDLL、DWORD FDFREASON、LPVOID lpvReserved)
{
静态std::唯一的任务线程;
静态std::唯一的ptr信号量;
开关(FDSON)
{
案例DLL\u进程\u附加:
{
禁用线程库调用(hinstDLL);
信号量重置(新信号量(0));
task_thread.reset(新任务线程([&](任务线程*线程){
while(thread&!thread->stopped()){
if(!信号量)
{
回来
}
信号量->等待();
如果(!thread | | thread->stopped())
{
回来
}
runTask();//执行一些函数
}
}, [&]{
if(信号量)
{
信号量->信号();
}
}));
}
打破
案例DLL\u进程\u分离:
{
task_thread.reset();//删除线程..触发析构函数
}
打破
}
返回TRUE;
}
但是,这将导致退出时程序挂起。。我必须通过任务管理器来杀死它。如果我拆下线程,一切都会正常工作并干净地退出(不管是在创建线程之后还是在析构函数中拆下线程)
那么,为什么在我加入线程时进程会挂起呢?调用
DllMain()
时会持有一个锁,因此等待线程退出最终是对DllMain()
的递归调用(thread\u DETACH
和process\u DETACH
)并挂起该锁
进一步阅读:调用
DllMain()
时会持有一个锁,因此等待线程退出最终是对DllMain()
(thread\u DETACH
和PROCESS\u DETACH
)的递归调用,并挂起该锁
进一步阅读:有许多关于在
DllMain()中做事的危险的文章。
谢谢!那我得多读些。似乎在上面的代码中获取互斥体也会导致死锁。。我必须找到另一种方法或遵循最佳实践,并在DLL\u THREAD\u DETACH
中发出事件信号。。有很多关于在DllMain()中做事的危险性的文章。
谢谢!那我得多读些。似乎在上面的代码中获取互斥体也会导致死锁。。我必须找到另一种方法或遵循最佳实践,并在DLL\u THREAD\u DETACH
中发出事件信号。。