基于C++ Equivalent to Java's BlockingQueue
void push(T const& value) { // original version
{
std::unique_lock<std::mutex> lock(this->d_mutex);
d_queue.push_front(value);
}
this->d_condition.notify_one();
}
void push(T const& value) { // my question
//{ // comment out the scope
std::unique_lock<std::mutex> lock(this->d_mutex);
d_queue.push_front(value);
//} // comment out the scope
this->d_condition.notify_one();
}
问题:为什么我们应该引入一个本地范围{}
来涵盖std::unique_lock
函数中的put
?是因为我们应该在调用notify_one
之前先释放锁定,否则在我们调用notify_one
时保持锁定?
T pop() {
std::unique_lock<std::mutex> lock(this->d_mutex);
this->d_condition.wait(lock, [=]{ return !this->d_queue.empty(); });
T rc(std::move(this->d_queue.back()));
this->d_queue.pop_back();
return rc;
}
问题:为什么我们应该在[=]
函数中使用pop
?
答案 0 :(得分:8)
是不是因为我们应该在调用
notify_one()
之前先释放锁定,否则在我们调用notify_one()
时保持锁定?
正确。在生产者线程释放之前,其他线程可能会旋转并尝试获取队列的锁定。哪会导致它被唤醒(因为条件变量),然后又回到睡眠状态(因为锁定)。
为什么我们应该在pop函数中使用
[=]
?
我们正在访问this
。 lambda需要通过某种方法访问d_queue
,他们选择按值复制this
。