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