4

考虑这个类:

#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;
    }
};

方法getVectorRef线程安全吗?

是否有可能在getVectorRef另一个线程的返回过程中弹出并调用insertElement,从而改变成员向量并且调用者getVectorRef得到错误的 const 引用?

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

4

1 回答 1

4

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

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

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

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

对于如何使接口线程安全的一些讨论,我推荐Anthony Williams 的C++ concurrency in action 。

于 2013-09-30T13:35:17.843 回答