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

C++11 how to identify atomic type at compile time (via mtl or defines)?

本文关键字:通过 类型 MTL 定义 编译 识别 C++11      更新时间:2023-10-16

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

我想知道是否有一些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
   }

那么有没有办法在定义/mtl 级别检查类型是否是原子的(如果需要,使用 boost)。

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

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

此外,甚至

可能无法仅从类型确定这一点,因为某些类型根据其内存对齐方式具有不同的原子性属性(而不会使原子性的对齐要求成为该类型的强制性要求)。

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

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

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

<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 涵盖。

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