为什么我们应该把' std::unique_lock '放在本地作用域下
why we should put `std::unique_lock` under a local scope?
基于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
。
相关文章:
- 未在作用域中声明unordered_map
- 有没有一种方法可以在编译时获得作用域类名
- C++quit()函数中可能存在作用域问题
- 未在此作用域OpenCV3.4中声明cvSaveImage
- 全局作用域中函数指针的赋值
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 是同一作用域的函数部分中的函数调用
- 未在此作用域中声明的函数和变量 (C++)
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 将作用域枚举转换为基础类型
- 表达式必须具有完整或无作用域的枚举图
- 在构造函数中输入对象时C++类成员作用域
- 无法让"std::enable_if"适用于无作用域枚举
- 为什么不能直接引用作用域枚举类成员,而不能为无作用域枚举生成类成员?
- 函数未在作用域中声明 / 如何结合使用 header.h、header.cpp 和 main.cpp?
- 错误:表达式必须具有算术、无作用域枚举或带有运算符重载的指针类型
- 如何在C++中访问作用域的变量输出?
- 重载时未在 C++ 的作用域错误中声明
- 作用域枚举和标准::get