简体   繁体   English

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

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

Suppose the following scenario:假设以下场景:

I have implemented my own QReadWriteLockGuard:我已经实现了自己的 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;
};

I have a "manager" object A, which holds an instance of object B.我有一个“经理”object A,它拥有一个 object B 的实例。

Object A has a method get_b: Object A有一个方法get_b:

const B& A::get_b() const
{
    QReadWriteLockGuard(_b_lock);
    return *_b;
}

Now, B of course has its substructure: attributes, public methods etc. Assume that another thread can rewrite the contents of _b at any time, or even delete them, if they are pointers.现在,B 当然有它的子结构:属性、公共方法等。假设另一个线程可以随时重写_b的内容,甚至删除它们,如果它们是指针的话。 However, it will call _b_lock.lockForWrite() first.但是,它会先调用_b_lock.lockForWrite()

Assume that B is not assignable (private assignment and copy operators).假设B不可赋值(私有赋值和复制运算符)。 Is it safe to do this:这样做是否安全:

A_instance.get_b().get_vector().at(i).do_stuff() ? A_instance.get_b().get_vector().at(i).do_stuff()

In other words, will the ReadWrite lock be unlocked before or after execution of do_stuff() ?换句话说,读写锁会在执行do_stuff()之前还是之后解锁? Or is it perhaps undefined?或者它可能是未定义的?

A const reference does not mean that the object is const , only that you cannot modify the object via that reference. const引用并不意味着 object 是const ,只是您不能通过该引用修改 object 。 If one thread has that const reference and reads it and another thread writes to the same object (via a non-const reference) then you have a data race.如果一个线程具有该const引用并读取它,而另一个线程写入同一个 object(通过非 const 引用),那么您将遇到数据竞争。

Your QReadWriteLockGuard releases the lock when A::get_b() returns, so it won't help.A::get_b()返回时,您的QReadWriteLockGuard会释放锁,因此无济于事。

For this line:对于这一行:

A_instance.get_b().get_vector().at(i).do_stuff();

Consider that it is more or less equivalent to考虑到它或多或少等同于

const B& b = A_instance.get_b();
b.get_vector().at(i).do_stuff();

and after the first line you already released the lock.在第一行之后,您已经释放了锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM