以下假设是正确的吗?
std::atomic<T>对象std::atomic<T>操作可以是无锁的,也可以是非无锁的,取决于平台。std::atomic_bool和std::atomic<bool> (以及其他类似的类型)实际上是相同的std::atomic_flag是唯一按标准保证平台无关的无锁操作的类。另外,在哪里可以找到关于std::memory_order的有用信息,以及如何正确地使用它?
发布于 2014-02-28 16:56:20
让我们一个接一个地检查一下。
std::atomic<T>对象是的,atomic对象在其所有访问器方法上都是完全同步的。
在访问原子类型时,唯一可能发生的数据争用发生在构造过程中,但它涉及构造原子对象A,通过使用memory_order_relaxed的原子指针将其地址传递给另一个线程,从而有意地绕过std::atomic的顺序一致性,然后从第二个线程访问A。所以,不要那么做?:)
说到构造,有三种方法可以初始化原子类型:
// Method 1: constructor
std::atomic<int> my_int(5);
// Method 2: atomic_init
std::atomic<int> my_int; // must be default constructed
std::atomic_init(&my_int, 5); // only allowed once
// Method 3: ATOMIC_VAR_INIT
// may be implemented using locks even if std::atomic<int> is lock-free
std::atomic<int> my_int = ATOMIC_VAR_INIT(5);使用后两种方法中的任何一种,同样的数据竞争可能性也适用。
std::atomic<T>操作可以是无锁的,也可以是非无锁的,取决于平台。对,是这样。对于所有的整体类型,您可以检查一些宏,这些宏可以告诉您给定的atomic专门化是否有时是无锁的,还是始终是无锁的。对于这三种情况,宏的值分别为0、1或2。宏的完整列表摘自标准的第29.4节,其中unspecified是"0、1或2“的替补:
#define ATOMIC_BOOL_LOCK_FREE unspecified
#define ATOMIC_CHAR_LOCK_FREE unspecified
#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
#define ATOMIC_SHORT_LOCK_FREE unspecified
#define ATOMIC_INT_LOCK_FREE unspecified
#define ATOMIC_LONG_LOCK_FREE unspecified
#define ATOMIC_LLONG_LOCK_FREE unspecified
#define ATOMIC_POINTER_LOCK_FREE unspecified请注意,这些定义同时适用于相应类型的无符号变体和符号变体。
如果#define为1,则必须在运行时进行检查。实现这一目标的步骤如下:
std::atomic<int> my_int;
if (my_int.is_lock_free()) {
// do lock-free stuff
}
if (std::atomic_is_lock_free(&my_int)) {
// also do lock-free stuff
}std::atomic_bool和std::atomic<bool> (以及其他类似的类型)实际上是相同的是的,为了您的方便,这些都是typedef。完整的清单载于标准表194:
Named type | Integral argument type
----------------+-----------------------
atomic_char | char
atomic_schar | signed char
atomic_uchar | unsigned char
atomic_short | short
atomic_ushort | unsigned short
atomic_int | int
atomic_uint | unsigned int
atomic_long | long
atomic_ulong | unsigned long
atomic_llong | long long
atomic_ullong | unsigned long long
atomic_char16_t | char16_t
atomic_char32_t | char32_t
atomic_wchar_t | wchar_tstd::atomic_flag是唯一按标准保证平台无关的无锁操作的类。正确,如标准第29.7/2节所保证。
请注意,除非您使用宏初始化atomic_flag,否则无法保证它的初始化状态如下:
std::atomic_flag guard = ATOMIC_FLAG_INIT; // guaranteed to be initialized cleared其他原子类型也有类似的宏,
该标准没有指定atomic_flag是否可以在构造过程中经历其他原子类型可能具有的相同的数据竞争。
std::memory_order的有用信息,以及如何正确地使用它?正如@WhozCraig所建议的,cppreference.com有最好的参考资料。
正如@erenon所暗示的,Boost.Atomic有一篇关于如何使用内存栅栏进行无锁编程的优秀文章。
https://stackoverflow.com/questions/22090348
复制相似问题