线程安全和`const`

Jam*_*kin 9 c++ multithreading

如何const(指针,引用和成员函数),在C++线程安全的帮助?

Mar*_*Pim 14

任何不可变的(即不可变的)数据本质上都是线程安全的 - 多个线程同时读取相同的只读数据没有风险,因为它永远不会改变!

在C++中将变量标记为const使其成为只读,从而使线程安全.

  • 并且假设它的初始化是线程安全的。 (2认同)
  • 还假设所有成员函数都是可重入的(即没有静态对象或其他共享数据) (2认同)

Bri*_*sen 6

多线程的主要问题是可变性.const限制了这一点,但既然你可以抛弃常量,那就不是万无一失的.

  • 没错,但你需要做额外的工作才能在脚下射击自己. (5认同)
  • 没有代码是万无一失的,但你必须防范墨菲,而不是针对马基雅维利. (3认同)
  • 我同意并且作为C#程序员这些天我当然会想念const& (2认同)

Pat*_*ick 6

const成员函数不应该改变状态,这样可以安全地同时从多个线程调用.但是线程安全不是const的目的,C++提供了mutable关键字和const_cast,这意味着const实际上并不保证线程安全,不应该依赖于此目的.


Evg*_*zin 5

Const 函数不是线程安全的。通常,您可以同时从不同线程调用 const 对象方法,但如果从不同线程调用非 const 和 const 方法,则会出现竞争条件。检查一下:

class Foo
{
    size_t size_;
public:
    ...
    size_t get_size() const
    {
        return size_
    }
};

class Bar
{
    boost::shared_ptr<Foo> foo_;
public:
    //accessor
    size_t get_size() const
    {
        size_t size = 0;
        if (foo_)
            size = foo_->size();
        return size;
    }
    //modifiers
    void init()
    {
        foo_ = new Foo;
    }

    void clear()
    {
        foo_ = boost::shared_ptr<Foo>();
    }
};
Run Code Online (Sandbox Code Playgroud)

如果有人调用init方法,然后同时调用clear和get_size方法,就会导致访问冲突。您必须使用读写锁习惯用法。可以同时调用多个访问器,同时只能调用一个修饰符。示例:

class Bar
{
    boost::shared_ptr<Foo> foo_;
    mutable tbb::spin_rw_mutex lock_;
public:
    //accessor
    size_t get_size() const
    {
        size_t size = 0;
        //lock modifiers
        rw_mutex_type::scoped_lock lock(mutex, false);
        if (foo_)
            size = foo_->size();
        return size;
    }
    //modifiers
    void init()
    {
        //lock accessor and modifiers
        rw_mutex_type::scoped_lock lock(mutex, true);
        foo_ = new Foo;
    }

    void clear()
    {
        //lock accessor and modifiers
        rw_mutex_type::scoped_lock lock(mutex, true);
        foo_ = boost::shared_ptr<Foo>();
    }
};
Run Code Online (Sandbox Code Playgroud)

tbb::spin_rw_lock 是线程构建块库中的互斥类