4

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

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

如果类型是原子的(如果需要,使用 boost),有什么方法可以检查定义/mtl 级别。

4

2 回答 2

10

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

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

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

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

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

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

于 2013-01-31T15:05:53.463 回答
8

标题<atomic>提供ATOMIC_INT_LOCK_FREE和朋友,用于所有各种大小的内置类型。这些是预处理器宏,如果类型的原子变体从不无锁,则定义为 0,如果有时无锁(例如,如果目标系统支持),则定义为 1,如果始终无锁,则定义为 2。例如,如果std::atomic<int>总是无锁,但std::atomic<long long>只是有时,则为ATOMIC_INT_LOCK_FREE2,然后ATOMIC_LLONG_LOCK_FREE为 1。指针类型由 . 覆盖ATOMIC_POINTER_LOCK_FREE

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

于 2013-01-31T16:06:17.523 回答