C++,Qt-锁定保护和返回对象的不可分配引用的安全性

C++, Qt - lock guard and the safety of returning an unassignable reference to an object

本文关键字:不可分 可分配 引用 安全性 对象 返回 Qt- 锁定 保护 C++      更新时间:2024-04-28

假设以下场景:

我已经实现了我自己的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();

在第一行之后,你已经松开了锁。