我想知道是否有可能确定给定的类型是否是原子的(这意味着您可以在没有互斥锁的情况下对其执行操作,而不会将自己置于危险之中)。
我想知道是否有一些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>
并让编译器处理它。