在 DLL_DETACHED 上通知分离的线程
Notify Detached Thread on DLL_DETACHED
我有以下代码创建一组线程并立即分离它们:
#include <mutex>
#include <thread>
#include <queue>
#include <atomic>
#include <functional>
class TGroup final
{
private:
std::mutex mutex;
std::condition_variable condition;
std::queue<std::function<void()>> tasks;
std::atomic_bool stop;
public:
TGroup();
~TGroup();
TGroup(const TGroup&) = delete;
TGroup& operator = (const TGroup&) = delete;
void terminate();
void execute(std::function<void()> &&task);
};
TGroup::TGroup() : mutex(), condition(), tasks(), stop(false)
{
for (std::size_t i = 0; i < std::thread::hardware_concurrency(); ++i)
{
std::thread([this] {
while(true)
{
std::unique_lock<std::mutex> lock(this->mutex);
condition.wait(lock, [this] {
return !this->tasks.empty() || this->stop;
});
if (this->stop)
{
lock.unlock();
break;
}
auto task = std::move(this->tasks.front());
this->tasks.pop();
lock.unlock();
task();
}
}).detach();
}
}
TGroup::~TGroup()
{
this->terminate();
}
void TGroup::terminate()
{
if (!this->stop)
{
std::unique_lock<std::mutex> lock(this->mutex);
this->stop = true;
lock.unlock();
this->condition.notify_all(); //Causes a crash on Windows but not MacOS or Linux..
}
}
void TGroup::execute(std::function<void()> &&task)
{
if (!this->stop)
{
std::unique_lock<std::mutex> lock(this->mutex);
this->tasks.emplace(task);
lock.unlock();
this->condition.notify_one();
}
}
在我的DLL_DETACHED
里面DLLMain
,我调用group.terminate()
。如果我在 TGroup.terminate()
.
中注释掉 this->condition.notify_all();
,它工作得很好
通知条件变量会导致死锁的原因是什么?它目前导致我的进程在我按下退出按钮时不退出(我必须使用 TaskManager 来终止它)。
有什么想法吗?
您的程序包含 *this
上的数据争用,在 TGroup
对象被销毁与唤醒的线程试图访问 this->tasks
和其他成员变量之间。因此它表现出未定义的行为。
当您不调用 notify_all()
时,您允许操作系统在正常进程关闭过程中终止休眠线程。
我有以下代码创建一组线程并立即分离它们:
#include <mutex>
#include <thread>
#include <queue>
#include <atomic>
#include <functional>
class TGroup final
{
private:
std::mutex mutex;
std::condition_variable condition;
std::queue<std::function<void()>> tasks;
std::atomic_bool stop;
public:
TGroup();
~TGroup();
TGroup(const TGroup&) = delete;
TGroup& operator = (const TGroup&) = delete;
void terminate();
void execute(std::function<void()> &&task);
};
TGroup::TGroup() : mutex(), condition(), tasks(), stop(false)
{
for (std::size_t i = 0; i < std::thread::hardware_concurrency(); ++i)
{
std::thread([this] {
while(true)
{
std::unique_lock<std::mutex> lock(this->mutex);
condition.wait(lock, [this] {
return !this->tasks.empty() || this->stop;
});
if (this->stop)
{
lock.unlock();
break;
}
auto task = std::move(this->tasks.front());
this->tasks.pop();
lock.unlock();
task();
}
}).detach();
}
}
TGroup::~TGroup()
{
this->terminate();
}
void TGroup::terminate()
{
if (!this->stop)
{
std::unique_lock<std::mutex> lock(this->mutex);
this->stop = true;
lock.unlock();
this->condition.notify_all(); //Causes a crash on Windows but not MacOS or Linux..
}
}
void TGroup::execute(std::function<void()> &&task)
{
if (!this->stop)
{
std::unique_lock<std::mutex> lock(this->mutex);
this->tasks.emplace(task);
lock.unlock();
this->condition.notify_one();
}
}
在我的DLL_DETACHED
里面DLLMain
,我调用group.terminate()
。如果我在 TGroup.terminate()
.
this->condition.notify_all();
,它工作得很好
通知条件变量会导致死锁的原因是什么?它目前导致我的进程在我按下退出按钮时不退出(我必须使用 TaskManager 来终止它)。
有什么想法吗?
您的程序包含 *this
上的数据争用,在 TGroup
对象被销毁与唤醒的线程试图访问 this->tasks
和其他成员变量之间。因此它表现出未定义的行为。
当您不调用 notify_all()
时,您允许操作系统在正常进程关闭过程中终止休眠线程。