C++,Qt-锁定保护和返回对象的不可分配引用的安全性
C++, Qt - lock guard and the safety of returning an unassignable reference to an object
假设以下场景:
我已经实现了我自己的QReadWriteLockGuard:
class QReadWriteLockGuard {
public:
explicit QReadWriteLockGuard(QReadWriteLock & m) : m(m) {m.lockForRead();}
~QReadWriteLockGuard() {m.unlock();}
QReadWriteLockGuard(QReadWriteLockGuard const &) = delete;
void operator=(QReadWriteLockGuard &) = delete;
private:
QReadWriteLock & m;
};
我有一个"管理器"对象a,它包含对象B的实例。
对象A有一个方法get_b:
const B& A::get_b() const
{
QReadWriteLockGuard(_b_lock);
return *_b;
}
现在,B当然有它的子结构:属性、公共方法等。假设另一个线程可以随时重写_b
的内容,甚至删除它们,如果它们是指针的话。但是,它将首先调用_b_lock.lockForWrite()
。
假设B
是不可赋值的(私有赋值和复制运算符(。这样做安全吗:
A_instance.get_b().get_vector().at(i).do_stuff()
?
换句话说,ReadWrite锁是在执行do_stuff()
之前还是之后解锁?或者它可能是未定义的?
const
引用并不意味着对象是const
,只是不能通过该引用修改对象。如果一个线程有const
引用并读取它,而另一个线程(通过非常数引用(写入同一对象,那么就存在数据竞争。
当A::get_b()
返回时,您的QReadWriteLockGuard
会释放锁,所以这不会有帮助。
对于这条线路:
A_instance.get_b().get_vector().at(i).do_stuff();
考虑一下它或多或少等同于
const B& b = A_instance.get_b();
b.get_vector().at(i).do_stuff();
在第一行之后,你已经松开了锁。
相关文章:
- 我可以为unordered_map分配特定的模组值吗?
- 堆分配对于大型块中的分页是否更有效?
- 如何接受可修改和不可修改的参数?
- 可移动但不可复制的对象:按值传递还是按引用传递?
- 在可拆卸线程完成操作时取消分配内存
- 可视化C++将分配移动到未初始化的对象?
- 在线程中使用堆可分配 >100MB 的 RAM
- 哪种类型特征表明该类型是可分配的?(元组,对)
- C++概念相同且可分配
- 如何使具有包含唯一指针的成员变量的类可复制可分配
- 使用 std::string 参数和不可移动/可复制参数构建 std::map
- 使用不可复制(但可移动)键移动地图分配时出错
- GCC C++11 删除移动可分配类的副本分配会阻止 std::sort 编译
- 如何使具有常量属性的类可分配
- 创建可分配的最大字符数组
- 如何使我自己的容器索引和可分配
- 为Fortran可分配程序在C中分配内存
- 移动包含向量<unique_ptr的可分配类<T>>
- 移动clang和gcc中可分配的lambda
- 对左值和右值的可分配引用