我有一个dll,它具有在高优先级线程中运行的高优先级功能。这个dll需要报告进度。基本上使用回调系统。问题是dll无法控制回调完成所需的时间。这意味着高优先级功能取决于回调的实现,这是不可接受的。
我们的想法是在中间有一个类来缓冲进度通知并调用回调。
我是C ++ 11的新手,它是线程功能并试图发现可能性。我有一个实现,但我有一个问题(至少有一个,我现在看到)。当线程在等待之后唤醒时,重新获取互斥锁并保持获取直到下一次等待。这意味着只要漫长的操作继续,就会获取锁定。添加进度将阻止此处。基本上很多代码都没有收获。我想把代码改成这个,但我不知道这是不是正确的实现。
Progress progress = queue.front();
queue.pop();
lock.unlock();
// Do lengthy operation with progress
lock.lock();
我想我需要等待条件变量,但不应该连接到锁。我不知道如何做到这一点。通过虚拟锁并使用不同的锁来保护队列?如何在C ++ 11中解决这个问题?
头文件
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <queue>
#include "Error.h"
#include "TypeDefinitions.h"
struct Progress
{
StateDescription State;
uint8 ProgressPercentage;
};
class ProgressIsolator
{
public:
ProgressIsolator();
virtual ~ProgressIsolator();
void ReportProgress(const Progress& progress);
void Finish();
private:
std::atomic<bool> shutdown;
std::condition_variable itemAvailable;
std::mutex mutex;
std::queue<Progress> queue;
std::thread worker;
void Work();
};
cpp文件
#include "ProgressIsolator.h"
ProgressIsolator::ProgressIsolator() :
shutdown(false),
itemAvailable(),
worker([this]{ Work(); }),
progressCallback(progressCallback),
completedCallback(completedCallback)
{
// TODO: only continue when worker thread is ready and listening?
}
ProgressIsolator::~ProgressIsolator()
{
Finish();
worker.join();
}
void ProgressIsolator::ReportProgress(const Progress& progress)
{
std::unique_lock<std::mutex> lock(mutex);
queue.push(progress);
itemAvailable.notify_one();
}
void ProgressIsolator::Finish()
{
shutdown = true;
itemAvailable.notify_one();
}
void ProgressIsolator::Work()
{
std::unique_lock<std::mutex> lock(mutex);
while (!shutdown)
{
itemAvailable.wait(lock);
while (!queue.empty())
{
Progress progress = queue.front();
queue.pop();
// Do lengthy operation with progress
}
}
}
答案 0 :(得分:0)
void ProgressIsolator::Work()
{
while (!shutdown)
{
Progress progress;
{
std::unique_lock<std::mutex> lock(mutex);
itemAvailable.wait(lock, [this] { return !queue.empty(); });
progress = queue.front();
queue.pop();
}
// Do lengthy operation with progress
}
}