为什么我们应该把' std::unique_lock '放在本地作用域下

why we should put `std::unique_lock` under a local scope?

本文关键字:作用域 lock 我们 std unique 为什么      更新时间:2023-10-16

基于c++的等效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();
    }

问题:为什么我们要引入一个局部作用域{}来覆盖put函数中的std::unique_lock ?这是因为我们应该在调用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函数中使用[=] ?

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

正确的。在生产者线程释放队列锁之前,另一个线程可能会启动并试图获取队列锁。这将导致它唤醒(因为条件变量),然后返回睡眠(因为锁)。

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

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