在DLL_DETACH中加入线程

问题描述 投票:0回答:1

我有一个注入到进程中的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()> 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;
}

但是,这将导致我的程序在退出时挂起。.我必须通过任务管理器将其杀死。如果我改为分离线程,则一切正常,然后干净地退出(创建线程后立即在析构函数中分离线程还是在析构函数中分离线程都没关系)。

所以为什么当我加入线程时进程挂起?

我有一个注入到进程中的DLL,并且当进程终止时,我希望线程在DLL卸载时终止。因此,我想到了以下内容:// std :: thread ...

multithreading c++11 winapi dll
1个回答
1
投票

DllMain()被调用时将持有一个锁,因此等待线程退出最终是对DllMain()THREAD_DETACHPROCESS_DETACH)的递归调用,并挂在该锁上。

© www.soinside.com 2019 - 2024. All rights reserved.