c ++中单个对象的线程安全容器

时间:2016-12-03 09:32:11

标签: c++ thread-safety

是否有一个c ++容器(单个编写器,多个读取器)用于存储始终可读/写(lockfree)的单个值?读取过时的版本很好。

我想到了类似的东西:

template <class T>
class Container {
    bool active = 0;
    T object[2];
public:
    void writeData(T t)
    {
        object[!active] = t;
        active = !active;
    }
    T readData()
    {
        return object[active];
    }
};

我想到的一个问题:

Read thread reads active = 0
Write thread happens (active = 1)
another Write thread starts and writes to 0
Read thread reads the data which is currently written to

原因是active不是原子的,但由于它是一个bool并且一次只发生一个写线程,所以两个可能的值都是可以接受的。

2 个答案:

答案 0 :(得分:0)

不是一个完整的解决方案,而是了解如何做到这一点:

假设您要存储的值是非基本类型(否则只使用atomic,请参阅http://en.cppreference.com/w/cpp/atomic/atomic)然后您可以使用atomic<Container*> current_container;之类的内容作为中心 - 指针到您的对象。在每个更新的writer中,使用更新的数据准备新的完整格式Container对象,并在完成设置current_container时指向新对象。

请注意,这种方法有一些注意事项:

    在编写器中
  • ,您无法在替换后立即删除Container的旧实例,因为您的某些读者可能仍在使用它。如果您的Container将被动态分配,那么这可能会变得棘手。您可能希望使用std::shared_ptr current_containeratomic_exchage作为更改值的方法(请参阅http://en.cppreference.com/w/cpp/memory/shared_ptr/atomic

  • 这种方法需要编写者为每次更新准备一个新版本的Container - 如果Container很大并且复制费用很高,这可能会很昂贵

    < / LI>

答案 1 :(得分:0)

我不知道即用型实施。但是,努力将这样的设施纳入C ++标准: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0561r3.html

该论文表明,对于完全线程安全和某种形式的回收,您需要解决相当复杂的问题。无论如何,本文中的规范应该有助于创建正确的实现。