包装原子类型并确保它保持原子状态

Fan*_*Fox 6 c++ multithreading boost thread-safety c++11

我有一个独特而有趣(可怕)的场景,迫使我做一些棘手的事情.问题如下:

  1. 我们需要一个原子类型来在实时线程和后台加载线程之间进行无锁同步.
  2. 类型(不幸的是)必须编译:

    一个.QNX只有c ++ 03,但支持boost::atomic.

    湾 Nucleus有c ++ 11但无法构建boost::atomic

这迫使我考虑使用boost::atomicstd::atomic.我接近这个的方法是生成一个新类型,它将所有功能转发到atomic平台上的相关类型.这个想法是这样的:


Atomic.hpp

namespace osal { namespace detail {

template <typename T, template <class> class TAtomic >
struct AtomicImpl {

    void store(T desired, memory_order order = osal::memory_order_seq_cst) 
    {
        _atomic.store(desired, order);
    }

    // ... Other api

private:

    AtomicImpl& operator=(const AtomicImpl& rhs);
    // ... Other blocked operations
    TAtomic<T> _atomic;
};

}}


#if defined QNX
    #include <osal/QNX/Atomic.hpp>
#elif defined NUCLEUS
    #include <osal/NUCLEUS/Atomic.hpp>
#endif
Run Code Online (Sandbox Code Playgroud)

这将列出一个类,它将转发到atomic具有正确API 的类型.幸运的是boost,std实现匹配几乎完全一致.


然后在每个单独的OS文件中,这样的事情:

核/ Atomic.hpp

#include <atomic>

namespace osal 
{ 

template <typename T> struct atomic
   {
      typedef detail::AtomicImpl<T, std::atomic> type;
   };
}
Run Code Online (Sandbox Code Playgroud)

这创建了原子类型,std::atomic允许使用如下:

osal::atomic<uint8_t>::type a;
a.store(1);
Run Code Online (Sandbox Code Playgroud)

为了处理存储器顺序的概念,存在类似的系统,其具有使用预处理器委托给每个OS实现的文件.在实施中,例如.Nucleus,我们有这个:

核/ MemoryOrder.hpp

#include <memory>
namespace osal {

using std::memory_order;
using std::memory_order_relaxed;
...
}
Run Code Online (Sandbox Code Playgroud)

显然,等效的using boost::...将在QNX文件中(幸运的是它们再次匹配!).

这个问题

这似乎有效.我可以制作原子并对其进行操作.我有一个问题:

这仍然是原子的吗?

既然我们已经在API中引入了间接,那么对原子对象的调用顺序是否会出现问题?

作为一个额外的问题,考虑到约束,有没有更好的方法来做到这一点?

Max*_*kin 0

Nucleus 具有 c++11 但无法构建boost::atomic

boost::atomic<T>type 是头文件,您可以使用它而无需构建boost::atomic库。

您可以boost::atomic<T>在两个平台上直接无条件使用(前提是您的平台支持)。

有一些boost::atomic库需要构建,请参阅srchttps://github.com/boostorg/atomictest的目录,但是,使用不需要这些。boost::atomic<T>