返回对数据成员的 const 引用的成员函数是线程安全的吗?

Jue*_*gen 5 c++ const-correctness thread-safety function-qualifier

考虑这个类:

#include <vector>

class A {
private:
    std::vector<int> m_vector;
public:
    void insertElement(int i) {
        m_vector.push_back(i);
    }
    const std::vector<int>& getVectorRef() const {
        return m_vector;
    }
};
Run Code Online (Sandbox Code Playgroud)

该方法getVectorRef线程安全吗?

是否有可能在另一个线程返回期间getVectorRef弹出并调用,insertElement从而导致成员向量发生更改并且调用者getVectorRef获得错误的 const 引用?

两个 const 限定符(一个用于向量,另一个用于成员函数)在线程安全上下文中没有意义吗?

Dav*_*eas 4

成员函数是线程安全的,而您的接口则不是。在设计为线程安全的类中,您无法生成对您维护的对象的引用,就好像用户保留该引用一样,她可以在其他操作到位时使用它。

成员函数在技术上是线程安全的。对成员的引用基本上是它的地址,并且该地址不能更改。无论其他线程在做什么,该引用将始终引用完全相同的对象。但这通常不是您主要关心的问题。真正关心的是用户可以用函数的返回来做什么,在这种情况下答案基本上是

一旦用户获得引用,通过它进行的任何访问在与原始对象中该成员的任何修改相结合时都将导致竞争条件。一旦放弃引用,就无法提供安全同步,无法从产生引用的类中创建线程安全接口。

如果您需要使访问线程安全,您可以选择复制值(在关键部分内)或提供更细粒度的函数来处理来自用户的更高级别的请求。

我推荐Anthony Williams 的C++ concurrency in action来进行一些有关如何使接口线程安全的讨论。