【问题标题】:Thread safety of const reference return of const methodconst方法的const引用返回的线程安全
【发布时间】:2013-10-06 09:08:45
【问题描述】:

考虑这个类:

#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限定符(一个用于载体,另一个方法)在线程安全的背景下没有意义?

【问题讨论】:

  • “线程安全”是一个被过度使用的词......它有时听起来像是你扔给一些代码的灵丹妙药,它以某种方式使并发编程变得容易。是的,getVectorRef 是“线程安全的”,但这些信息有什么用?您仍然可以使用给定的界面创建大量损坏的代码。您仍然需要了解您的代码在做什么!
  • 您需要确保同步对线程之间的向量的访问,请参阅stackoverflow.com/questions/4346742/…以获取更多信息。 span>

标签: c++ thread-safety const-method


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2016-09-05
    • 2011-06-24
    • 1970-01-01
    • 2017-03-19
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多