线程安全设置

Rob*_*ner 6 c++ multithreading synchronization boost atomic

我正在编写一些可以从我的多线程应用程序中的任何位置访问的设置类.我会经常阅读这些设置(因此读取访问应该很快),但它们不是经常编写的.

对于原始数据类型,它看起来像boost::atomic我需要的东西,所以我想出了这样的东西:

class UInt16Setting
{
    private:
        boost::atomic<uint16_t> _Value;
    public:
        uint16_t getValue() const { return _Value.load(boost::memory_order_relaxed); }
        void setValue(uint16_t value) { _Value.store(value, boost::memory_order_relaxed); }
};
Run Code Online (Sandbox Code Playgroud)

问题1:我不确定内存排序.我认为在我的应用程序中我并不关心内存排序(是吗?).我只是想确保getValue()始终返回一个未损坏的值(旧的或新的).我的内存订购设置是否正确?

问题2:这种方法是否boost::atomic建议用于此类同步?或者是否有其他构造提供更好的读取性能?

我还需要在我的应用程序中使用一些更复杂的设置类型,std::string例如boost::asio::ip::tcp::endpoints 列表.我认为所有这些设置值都是不可变的.因此,一旦我使用setValue()值设置,值本身(std::string或端点列表本身)不再更改.所以我只想确保我得到旧值或新值,但不是一些损坏的状态.

问题3:这种方法是否有效boost::atomic<std::string>?如果没有,有什么替代方案?

问题4:更复杂的设置类型如端点列表如何?你会推荐类似的东西boost::atomic<boost::shared_ptr<std::vector<boost::asio::ip::tcp::endpoint>>>吗?如果不是,那会更好吗?

use*_*672 2

Q1,如果您在读取原子后不尝试读取任何共享非原子变量,则正确。内存屏障仅同步对原子操作之间可能发生的非原子变量的访问

Q2 我不知道(但见下文)

Q3 应该可以工作(如果可以编译)。然而,

 atomic<string> 
Run Code Online (Sandbox Code Playgroud)

可能不是无锁的

Q4 应该可以工作,但同样,该实现不可能是无锁的(实现无锁的shared_ptr 是一个具有挑战性且专利挖掘的领域)。

因此,如果您的配置包含大小超过 1 个机器字的数据(CPU 本机原子通常适用),那么读者-作者锁(正如 Damon 在评论中建议的那样)可能会更简单,甚至更有效。

[编辑]但是,

atomic<shared_ptr<TheWholeStructContainigAll> > 
Run Code Online (Sandbox Code Playgroud)

即使是非无锁也可能有一定的意义:这种方法可以最大限度地减少需要多个连贯值的读者的冲突概率,尽管编写者应该在每次更改某些内容时制作整个“参数表”的新副本。