考虑这个课程:
#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引用?< / p>
在线程安全的上下文中,有两个const限定符(一个用于向量而另一个用于方法)没有意义吗?
答案 0 :(得分:4)
成员函数线程安全,您的界面不是。在设计为线程安全的类中,您不能将引用提供给您维护的对象,就像用户保持引用一样,她可以在其他操作到位时使用它。 / p>
成员函数在技术上是线程安全的。对成员的引用基本上是它的地址,并且该地址不能更改。无论其他线程正在做什么,引用将始终引用完全相同的对象。但这通常不是你主要担心的问题。真正关心的是用户可以通过函数的返回做什么,在这种情况下答案基本上是 nothing 。
只要用户获得引用,当与原始对象中该成员的任何修改结合使用时,对它的任何访问都将导致竞争条件。提供引用后,您无法提供安全同步,无法从产生引用的类中创建线程安全接口。
如果您需要使访问线程安全,您可以选择复制值(在关键部分内)或提供更细粒度的函数来处理来自用户的更高级别请求。
我推荐Anthony Williams讨论如何使接口线程安全的 C ++并发操作。