我写了一个共享优先级队列类。
为了发出停止提供数据的信号,我使用方法Cancel()
,它将标志设置done
为 false,并且不允许应用程序从队列中写入/读取任何数据。我不确定与andstd::atomic<bool>
结合使用。我不确定,如果我的解决方案是线程安全的或可能发生竞争条件:std::mutex
std::condition_variable
方法的原始版本Enqueue
是:
std::deque<T> deque;
std::mutex mtx;
std::condition_variable cv;
std::atomic<bool> done;
SharedPriorityQueue() : done(false)
{
}
~SharedPriorityQueue()
{
Cancel();
}
void Enqueue(T item)
{
if (done)
{
return;
}
std::lock_guard<std::mutex> lock(mtx);
deque.push_back(item);
cv.notify_one();
}
但是,可以done
通过互斥锁将变量(原子布尔)与锁定机制分开吗?
要取消队列,我使用此构造:
void Cancel()
{
if (done)
{
return;
}
done = true;
cv.notify_all();
}
以下设计的最佳解决方案是什么?
// A)
void Enqueue(T item)
{
if (done)
{
return;
}
{
std::lock_guard<std::mutex> lock(mtx); // lock is released before notify call
deque.push_back(item);
}
cv.notify_one();
}
// B)
void Enqueue(T item)
{
{
std::lock_guard<std::mutex> lock(mtx); // done is atomic bool and protected by the lock along with data (deque)
if (done) // atomic bool
{
return;
}
deque.push_back(item);
}
cv.notify_one();
}
// C)
void Enqueue(T item)
{
{
std::lock_guard<std::mutex> lock(mtx); // done is NOT atomic bool and is protected by the lock along with data (deque)
if (done) // simple bool
{
return;
}
deque.push_back(item);
}
cv.notify_one();
}
等候人员:
bool Dequeue(T& item)
{
std::unique_lock<std::mutex> lock(mtx);
while (!done && deque.empty())
{
cv.wait(lock);
}
if (!deque.empty())
{
item = deque.front();
deque.pop_front();
}
if (done)
{
return false;
}
return true;
}