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

时间:2013-01-31 14:21:39

标签: c++ boost c++11 atomic

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

我想知道是否有一些atomic(type)定义可以确定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
   }

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

2 个答案:

答案 0 :(得分:10)

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

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

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

相反,您应该使用提供的std::atomic<T>实现,它应该为给定平台上可用的原子操作(具有给定的内存约束)提供最有效的实现。

通过使用特定于平台的内存栅栏或原子访问指令,即使底层内存模型为'裸'本机类型提供原子性,此类实现也可以提供无锁原子类型。 / p>

您可以使用std::atomic<T>::is_lockfree()来确定此类实现是否需要使用锁定。

答案 1 :(得分: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.指针类型由{{1}覆盖}。

ATOMIC_POINTER_LOCK_FREE无法锁定时,您可以使用这些宏来决定使用普通int和互斥锁,但在大多数情况下,最好只编写std::atomic<int>和让编译器处理它。