У меня есть следующий код, который создает группу потоков и немедленно их отсоединяет:
#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()
. Он прекрасно работает, если я закомментирую this->condition.notify_all();
в TGroup.terminate()
.
. Есть ли причина, по которой уведомление условной переменной может привести к тупику? В настоящее время мой процесс НЕ завершается, когда я нажимаю кнопку выхода (мне нужно использовать TaskManager, чтобы убить его).
Есть идеи?