C++ 11如何在编译时识别原子类型(通过mtl或者定义)?

myW*_*SON 4 c++ boost atomic c++11

我想知道是否有可能确定给定的类型是否是原子的(这意味着你可以在没有互斥的情况下对其执行操作,而不是让自己处于危险之中).

我想知道是否有一些atomic(type)定义可以确定类型是否是原子的.为了创建类似的东西DEFINE( (int)(do) );会创建伪代码,如:

   int _do;

#if !atomic(int)
    mutex do_mutex;
#endif   

   void set_do(int do)
   {
#if atomic(int)
       _do = do;
#else
       lock(do_mutex);
       _do = do;
#endif
   }
Run Code Online (Sandbox Code Playgroud)

如果type是atomic(如果需要,使用boost),那么有没有办法检查define/mtl级别.

Joe*_*rgB 10

在预处理时,您无法执行此类操作,因为该确定需要有关类型及其名称的语义信息,这些信息在预处理期间不可用.

is_atomic<T>实现必须提供模板化类型特征,但即使在C++ 11中也不可用.它的实用程序非常有限,因为在支持线程的平台上,拥有原子类型是相当不寻常的.

此外,甚至可能无法单独从类型中确定这一点,因为某些类型具有不同的原子性属性,具体取决于它们的内存对齐(不对类型强制执行原子性的对齐要求).

相反,你应该使用所提供的实施std::atomic<T>,这应该提供原子操作(与给定的内存限制)给定的平台上可用的最高效的实现.

通过使用特定于平台的内存栅栏或原子访问指令,即使底层内存模型为没有 "裸"本机类型提供原子性,这样的实现也可能能够提供无锁原子类型.

您可以使用std::atomic<T>::is_lockfree()来确定此类实现是否需要在引擎盖下使用锁.


Ant*_*ams 8

<atomic>头提供ATOMIC_INT_LOCK_FREE和朋友,对内建类型的所有各种尺寸.这些是预处理器宏,如果类型的原子变量永远不会被锁定,则定义为0;如果有时无锁定(例如,如果目标系统支持它),则定义为1;如果它始终是无锁定则定义为2.例如,如果std::atomic<int>总是无锁,但std::atomic<long long>只是有时,那么ATOMIC_INT_LOCK_FREE将是2,并且ATOMIC_LLONG_LOCK_FREE将是1.指针类型被覆盖ATOMIC_POINTER_LOCK_FREE.

你可以使用这些宏来决定在没有锁定int时使用普通和互斥std::atomic<int>,但在大多数情况下你最好只是编写std::atomic<int>并让编译器处理它.