为什么我们应该在本地范围内放置`std :: unique_lock`?

时间:2014-06-26 19:08:43

标签: c++ c++11

基于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

1 个答案:

答案 0 :(得分:8)

  

是不是因为我们应该在调用notify_one()之前先释放锁定,否则在我们调用notify_one()时保持锁定?

正确。在生产者线程释放之前,其他线程可能会旋转并尝试获取队列的锁定。哪会导致它被唤醒(因为条件变量),然后又回到睡眠状态(因为锁定)。

  

为什么我们应该在pop函数中使用[=]

我们正在访问this。 lambda需要通过某种方法访问d_queue,他们选择按值复制this