首页 文章

当C const方法同步可变状态时,非const方法也必须这样做吗?

提问于
浏览
1

根据Herb Sutter(http://isocpp.org/blog/2012/12/you-dont-know-const-and-mutable-herb-sutter),在C 11中,const方法不能逐位改变对象,或者如果它们具有可变数据成员,则必须执行内部同步(例如,使用互斥) .

我的问题是,非const方法是否也必须获取互斥锁?或者,如果用户想要同时在同一个对象上混合const和非const方法,他们是否可以依赖用户必须执行的外部同步?

编辑:换句话说,以下类是线程安全的吗?以下课程是否提供了Sutter的"basic thread safety guarantee"(来自part 4b of GOTW #95)?

#include <thread>

class C {
  public:
  void const_method() const
  {
    std::lock_guard<std::mutex> g(m);
    i = 2;
  }

  void non_const_method()
  {
    // std::lock_guard<std::mutex> g(m); // <-- is this needed?
    i = 1;
  }

  private:
  mutable int i;
  mutable std::mutex m;
};

2 回答

  • 0

    不,你的 class 本身并不是线程安全的 .

    void non_const_method()
    {
        // std::lock_guard<std::mutex> g(m); // <-- is this needed?
        i = 1;
    }
    

    以上不是线程安全的,因为多个线程可以调用该函数,从而同时改变 i .

    所以回答:

    以下课程是否提供Sutter的“基本线程安全保证”

    然后是的,该类提供"basic thread safety guarantee" . 您无法从另一个实例修改一个实例,并且该类的 const 方法是线程安全的 .

    您必须使用某种外部同步才能在多个线程中的同一实例上使用该类的可变函数,但您的非可变函数不需要外部同步 .

  • 4

    理想情况下,作者需要获得比读者更严格的锁定 . 您可能已经争论过读者是否需要获得锁定(但您提出了另一种方式) . 作家更多的是导致数据不一致的原因 .

    通过严格锁定,我的意思是在锁定协议中读取器锁定和写入器锁定是可能的 - 然后编写器锁定将更严格 . 在大多数实现中,获得写入锁定的线程会阻止所有其他线程获得任何类型的锁定,但是可以同时获取读取器锁定 . 因此,非const函数理想情况下需要写入锁定,但 const 函数可能只需要读取器锁定 - 从而允许并行执行相同的函数(或相同对象的类似函数) .

    是的,锁定协议可能不会优先考虑等待读取器线程等待的编写器线程 . 但是,这是实施细节 .

相关问题