前面三篇文章《C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)》、《C++11 并发指南六( <atomic> 类型详解二 std::atomic )》、《C++11 并发指南六(atomic 类型详解三 std::atomic (续))》都是采用 C++ 的方式介绍原子对象,本节我会给大家介绍 C++11 原子操作中 C 风格的 API。
总地来说,C++11 标准中规定了两大类原子对象,std::atomic_flag 和 std::atomic,前者 std::atomic_flag 一种最简单的原子布尔类型,只支持两种操作,test-and-set 和 clear。而 std::atomic 是模板类,一个模板类型为 T 的原子对象中封装了一个类型为 T 的值,并且C++11 标准中除了定义基本 std::atomic 模板类型外,还提供了针对整形(integral)和指针类型的特化实现,提供了大量的 API,极大地方便了开发者使用。下面我分别介绍基于 std::atomic_flag 和 std::atomic 的 C 风格 API。
基于 std::atomic_flag 类型的 C 风格 API
- atomic_flag_test_and_set
bool atomic_flag_test_and_set (volatile atomic_flag* obj) noexcept;
bool atomic_flag_test_and_set (atomic_flag* obj) noexcept;
- 检测并设置 std::atomic_flag 的值,并返回 std::atomic_flag 的旧值,和 std::atomic::test_and_set() 成员函数的功能相同,整个过程也是原子的,默认的内存序为memory_order_seq_cst。
- atomic_flag_test_and_set_explicit
bool atomic_flag_test_and_set (volatile atomic_flag* obj, memory_order sync) noexcept;
bool atomic_flag_test_and_set (atomic_flag* obj, memory_order sync) noexcept;
- 检测并设置 std::atomic_flag 的值,并返回 std::atomic_flag 的旧值,和 std::atomic::test_and_set() 成员函数的功能相同,整个过程也是原子的。sync 参数指定了内存序(Memory Order),可能的取值如下:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_flag_clear
void atomic_flag_clear (volatile atomic_flag* obj) noexcept;
void atomic_flag_clear (atomic_flag* obj) noexcept;
- 清除 std::atomic_flag 对象,并设置它的值为 false,和 std::atomic::clear() 成员函数的功能相同,整个过程也是原子的,默认的内存序为memory_order_seq_cst。
- atomic_flag_clear_explicit
void atomic_flag_clear (volatile atomic_flag* obj, memory_order sync) noexcept;
void atomic_flag_clear (atomic_flag* obj, memory_order sync) noexcept;
- 清除 std::atomic_flag 对象,并设置它的值为 false,和 std::atomic::clear() 成员函数的功能相同,整个过程也是原子的,sync 参数指定了内存序(Memory Order),可能的取值如下:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
基于 std::atomic 模板类型的 C 风格 API
- atomic_is_lock_free
| template (1) |
template <class T> bool atomic_is_lock_free (const volatile atomic<T>* obj) noexcept;
template <class T> bool atomic_is_lock_free (const atomic<T>* obj) noexcept;
|
| overloads (2) |
bool atomic_is_lock_free (const volatile A* obj) noexcept;
bool atomic_is_lock_free (const A* obj) noexcept;
|
- 判断该 std::atomic 对象是否具备 lock-free 的特性。如果某个对象满足 lock-free 特性,在多个线程访问该对象时不会导致线程阻塞。(可能使用某种事务内存transactional memory 方法实现 lock-free 的特性)。
- atomic_init
| template (1) |
template <class T> void atomic_init (volatile atomic<T>* obj, T val) noexcept;
template <class T> void atomic_init (atomic<T>* obj, T val) noexcept;
|
| overloads (2) |
void atomic_init (volatile A* obj, T val) noexcept;
void atomic_init (A* obj, T val) noexcept;
|
- 初始化原子对象。val 指定原子对象的初始值。如果对一个已初始化的原子对象再次调用 atomic_init(),则会导致未定义行为(undefined behavior),如果你想修改原子对象的值,应该使用 std::atomic_store();
- atomic_store
| template (1) |
template <class T> void atomic_store (volatile atomic<T>* obj, T val) noexcept;
template <class T> void atomic_store (atomic<T>* obj, T val) noexcept;
|
| overloads (2) |
void atomic_store (volatile A* obj, T val) noexcept;
void atomic_store (A* obj, T val) noexcept;
|
- 修改原子对象的值,默认的内存序为memory_order_seq_cst。该函数相当于 std::atomic 对象的 store 或者operator=() 成员函数,如果你需要显式指定内存序,应该使用atomic_store_explicit。
- atomic_store_explicit
- 修改原子对象的值。该函数相当于 std::atomic 对象的 store 或者operator=() 成员函数,sync 指定了内存序,可取的参数为:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_release |
Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_load
| template (1) |
template <class T> T atomic_load (const volatile atomic<T>* obj) noexcept;
template <class T> T atomic_load (const atomic<T>* obj) noexcept;
|
| overloads (2) |
T atomic_load (const volatile A* obj) noexcept;
T atomic_load (const A* obj) noexcept;
|
- 读取被封装的值,默认的内存序为memory_order_seq_cst。该函数与 std::atomic 对象的atomic::load()和atomic::operator T() 成员函数等价。
- atomic_load_explicit
| template (1) |
template <class T>
T atomic_load_explicit (const volatile atomic<T>* obj, memory_order sync) noexcept;
template <class T>
T atomic_load_explicit (const atomic<T>* obj, memory_order sync) noexcept;
|
| overloads (2) |
T atomic_load_explicit (const volatile A* obj, memory_order sync) noexcept;
T atomic_load_explicit (const A* obj, memory_order sync) noexcept;
|
- 读取被封装的值,参数 sync 设置内存序(Memory Order),可能的取值如下:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_seq_cst |
Sequentially consistent |
- 该函数与 std::atomic 对象的atomic::load() 成员函数等价。
- atomic_exchange
| template (1) |
template <class T> T atomic_exchange (volatile atomic<T>* obj, T val) noexcept;
template <class T> T atomic_exchange (atomic<T>* obj, T val) noexcept;
|
| overloads (2) |
T atomic_exchange (volatile A* obj, T val) noexcept;
T atomic_exchange (A* obj, T val) noexcept;
|
- 读取并修改被封装的值,exchange 会将 val 指定的值替换掉之前该原子对象封装的值,并返回之前该原子对象封装的值,整个过程是原子的(因此exchange 操作也称为 read-modify-write 操作)。该函数与 std::atomic 对象的atomic::exchange() 成员函数等价。
- atomic_exchange_explicit
| template (1) |
template <class T>
T atomic_store_explicit (volatile atomic<T>* obj, T val, memory_order sync) noexcept;
template <class T>
T atomic_store_explicit (atomic<T>* obj, T val, memory_order sync) noexcept;
|
| overloads (2) |
T atomic_store_explicit (volatile A* obj, T val, memory_order sync) noexcept;
T atomic_store_explicit (A* obj, T val, memory_order sync) noexcept;
|
- 读取并修改被封装的值,exchange 会将 val 指定的值替换掉之前该原子对象封装的值,并返回之前该原子对象封装的值,整个过程是原子的(因此exchange 操作也称为 read-modify-write 操作)。sync参数指定内存序(Memory Order),可能的取值如下:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_compare_exchange_weak
| template (1) |
template <class T>
bool atomic_compare_exchange_weak (volatile atomic<T>* obj, T* expected, T val) noexcept;
template <class T>
bool atomic_compare_exchange_weak (atomic<T>* obj, T* expected, T val) noexcept;
|
| overloads (2) |
bool atomic_compare_exchange_weak (volatile A* obj, T* expected, T val) noexcept;
bool atomic_compare_exchange_weak (A* obj, T* expected, T val) noexcept;
|
- 比较并交换被封装的值(weak)与参数 expected 所指定的值是否相等,如果:
- 相等,则用 val 替换原子对象的旧值。
- 不相等,则用原子对象的旧值替换 expected ,因此调用该函数之后,如果被该原子对象封装的值与参数 expected 所指定的值不相等,expected 中的内容就是原子对象的旧值。
- 该函数通常会读取原子对象封装的值,如果比较为 true(即原子对象的值等于 expected),则替换原子对象的旧值,但整个操作是原子的,在某个线程读取和修改该原子对象时,另外的线程不能对读取和修改该原子对象。
-
注意,该函数直接比较原子对象所封装的值与参数 expected 的物理内容,所以某些情况下,对象的比较操作在使用
operator==() 判断时相等,但 atomic_compare_exchange_weak
判断时却可能失败,因为对象底层的物理内容中可能存在位对齐或其他逻辑表示相同但是物理表示不同的值(比如 true 和 2 或
3,它们在逻辑上都表示"真",但在物理上两者的表示并不相同)。
-
与 atomic_compare_exchange_strong 不同, weak 版本的 compare-and-exchange 操作允许(spuriously 地)返回 false(即原子对象所封装的值与参数 expected 的物理内容相同,但却仍然返回 false),不过在某些需要循环操作的算法下这是可以接受的,并且在一些平台下 compare_exchange_weak 的性能更好 。如果 atomic_compare_exchange_weak 的判断确实发生了伪失败(spurious failures)——即使原子对象所封装的值与参数 expected 的物理内容相同,但判断操作的结果却为 false,atomic_compare_exchange_weak 函数返回 false,并且参数
expected 的值不会改变。
- atomic_compare_exchange_weak_explicit
| template (1) |
template <class T>
bool atomic_compare_exchange_weak_explicit (volatile atomic<T>* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
template <class T>
bool atomic_compare_exchange_weak_explicit (atomic<T>* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
|
| overloads (2) |
bool atomic_compare_exchange_weak_explicit (volatile A* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
bool atomic_compare_exchange_weak_explicit (A* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
|
- 比较并交换被封装的值(weak)与参数 expected 所指定的值是否相等,如果:
- 相等,则用 val 替换原子对象的旧值。
- 不相等,则用原子对象的旧值替换 expected ,因此调用该函数之后,如果被该原子对象封装的值与参数 expected 所指定的值不相等,expected 中的内容就是原子对象的旧值。
- 该函数通常会读取原子对象封装的值,如果比较为 true(即原子对象的值等于 expected),则替换原子对象的旧值,但整个操作是原子的,在某个线程读取和修改该原子对象时,另外的线程不能对读取和修改该原子对象。
内存序(Memory Order)的选择取决于比较操作结果,如果比较结果为 true(即原子对象的值等于 expected),则选择参数 success 指定的内存序,否则选择参数 failure 所指定的内存序。
-
注意,该函数直接比较原子对象所封装的值与参数 expected 的物理内容,所以某些情况下,对象的比较操作在使用
operator==() 判断时相等,但 compare_exchange_weak
判断时却可能失败,因为对象底层的物理内容中可能存在位对齐或其他逻辑表示相同但是物理表示不同的值(比如 true 和 2 或
3,它们在逻辑上都表示"真",但在物理上两者的表示并不相同)。
-
与 atomic_compare_exchange_strong 不同, weak 版本的 compare-and-exchange 操作允许(spuriously 地)返回 false(即原子对象所封装的值与参数 expected 的物理内容相同,但却仍然返回 false),不过在某些需要循环操作的算法下这是可以接受的,并且在一些平台下 compare_exchange_weak 的性能更好 。如果 atomic_compare_exchange_weak 的判断确实发生了伪失败(spurious failures)——即使原子对象所封装的值与参数 expected 的物理内容相同,但判断操作的结果却为 false,atomic_compare_exchange_weak函数返回 false,并且参数
expected 的值不会改变。
- 对于某些不需要采用循环操作的算法而言, 通常采用 atomic_compare_exchange_strong 更好。另外,该函数的内存序由 sync 参数指定,可选条件如下:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_compare_exchange_strong
| template (1) |
template <class T>
bool atomic_compare_exchange_strong (volatile atomic<T>* obj, T* expected, T val) noexcept;
template <class T>
bool atomic_compare_exchange_strong (atomic<T>* obj, T* expected, T val) noexcept;
|
| overloads (2) |
bool atomic_compare_exchange_strong (volatile A* obj, T* expected, T val) noexcept;
bool atomic_compare_exchange_strong (A* obj, T* expected, T val) noexcept;
|
- 比较并交换被封装的值(strong)与参数 expected 所指定的值是否相等,如果:
- 相等,则用 val 替换原子对象的旧值。
- 不相等,则用原子对象的旧值替换 expected ,因此调用该函数之后,如果被该原子对象封装的值与参数 expected 所指定的值不相等,expected 中的内容就是原子对象的旧值。
- 该函数通常会读取原子对象封装的值,如果比较为 true(即原子对象的值等于 expected),则替换原子对象的旧值,但整个操作是原子的,在某个线程读取和修改该原子对象时,另外的线程不能对读取和修改该原子对象。
-
注意,该函数直接比较原子对象所封装的值与参数 expected 的物理内容,所以某些情况下,对象的比较操作在使用
operator==() 判断时相等,但 compare_exchange_weak
判断时却可能失败,因为对象底层的物理内容中可能存在位对齐或其他逻辑表示相同但是物理表示不同的值(比如 true 和 2 或
3,它们在逻辑上都表示"真",但在物理上两者的表示并不相同)。
- 与 atomic_compare_exchange_weak 不同, strong版本的 compare-and-exchange 操作不允许(spuriously 地)返回 false,即原子对象所封装的值与参数 expected 的物理内容相同,比较操作一定会为 true。不过在某些平台下,如果算法本身需要循环操作来做检查, atomic_compare_exchange_weak 的性能会更好。
-
因此对于某些不需要采用循环操作的算法而言, 通常采用 atomic_compare_exchange_strong 更好。
- atomic_compare_exchange_strong_explicit
| template (1) |
template <class T>
bool atomic_compare_exchange_strong_explicit (volatile atomic<T>* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
template <class T>
bool atomic_compare_exchange_strong_explicit (atomic<T>* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
|
| overloads (2) |
bool atomic_compare_exchange_strong_explicit (volatile A* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
bool atomic_compare_exchange_strong_explicit (A* obj,
T* expected, T val, memory_order success, memory_order failure) noexcept;
|
- 比较并交换被封装的值(strong)与参数 expected 所指定的值是否相等,如果:
- 相等,则用 val 替换原子对象的旧值。
- 不相等,则用原子对象的旧值替换 expected ,因此调用该函数之后,如果被该原子对象封装的值与参数 expected 所指定的值不相等,expected 中的内容就是原子对象的旧值。
- 该函数通常会读取原子对象封装的值,如果比较为 true(即原子对象的值等于 expected),则替换原子对象的旧值,但整个操作是原子的,在某个线程读取和修改该原子对象时,另外的线程不能对读取和修改该原子对象。
内存序(Memory Order)的选择取决于比较操作结果,如果比较结果为 true(即原子对象的值等于 expected),则选择参数 success 指定的内存序,否则选择参数 failure 所指定的内存序。
-
注意,该函数直接比较原子对象所封装的值与参数 expected 的物理内容,所以某些情况下,对象的比较操作在使用
operator==() 判断时相等,但 compare_exchange_weak
判断时却可能失败,因为对象底层的物理内容中可能存在位对齐或其他逻辑表示相同但是物理表示不同的值(比如 true 和 2 或
3,它们在逻辑上都表示"真",但在物理上两者的表示并不相同)。
- 与atomic_compare_exchange_weak 不同, strong版本的 compare-and-exchange 操作不允许(spuriously 地)返回 false,即原子对象所封装的值与参数 expected 的物理内容相同,比较操作一定会为 true。不过在某些平台下,如果算法本身需要循环操作来做检查, atomic_compare_exchange_weak 的性能会更好。
-
因此对于某些不需要采用循环操作的算法而言, 通常采用 atomic_compare_exchange_strong 更好。另外,该函数的内存序由 sync 参数指定,可选条件如下:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_fetch_add
| template (integral) (1) |
template <class T> T atomic_fetch_add (volatile atomic<T>* obj, T val) noexcept;
template <class T> T atomic_fetch_add (atomic<T>* obj, T val) noexcept;
|
| template (pointer) (2) |
template <class U> U* atomic_fetch_add (volatile atomic<U*>* obj, ptrdiff_t val) noexcept;
template <class U> U* atomic_fetch_add (atomic<U*>* obj, ptrdiff_t val) noexcept;
|
| overloads (3) |
T atomic_fetch_add (volatile A* obj, M val) noexcept;
T atomic_fetch_add (A* obj, M val) noexcept;
|
- 将原子对象的封装值加 val,并返回原子对象的旧值(适用于整形和指针类型的 std::atomic 特化版本),整个过程是原子的。该函数默认内存序为 memory_order_seq_cst。
- 该函数等价于 std::atomic 对象的atomic::fetch_add和 atomic::operator+= 成员函数。
- atomic_fetch_add_explicit
| template (integral) (1) |
template <class T>
T atomic_fetch_add_explicit (volatile atomic<T>* obj,
T val, memory_order sync) noexcept;
template <class T>
T atomic_fetch_add_explicit (atomic<T>* obj,
T val, memory_order sync) noexcept;
|
| template (pointer) (2) |
template <class U>
U* atomic_fetch_add_explicit (volatile atomic<U*>* obj,
ptrdiff_t val, memory_order sync) noexcept;
template <class U>
U* atomic_fetch_add_explicit (atomic<U*>* obj,
ptrdiff_t val, memory_order sync) noexcept;
|
| overloads (3) |
T atomic_fetch_add_explicit (volatile A* obj, M val, memory_order sync) noexcept;
T atomic_fetch_add_explicit (A* obj, M val, memory_order sync) noexcept;
|
- 将原子对象的封装值加 val,并返回原子对象的旧值(适用于整形和指针类型的 std::atomic 特化版本),整个过程是原子的。
- 该函数等价于 std::atomic 对象的atomic::fetch_add成员函数。sync 参数指定内存序:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_fetch_sub
| template (integral) (1) |
template <class T> T atomic_fetch_sub (volatile atomic<T>* obj, T val) noexcept;
template <class T> T atomic_fetch_sub (atomic<T>* obj, T val) noexcept;
|
| template (pointer) (2) |
template <class U> U* atomic_fetch_sub (volatile atomic<U*>* obj, ptrdiff_t val) noexcept;
template <class U> U* atomic_fetch_sub (atomic<U*>* obj, ptrdiff_t val) noexcept;
|
| overloads (3) |
T atomic_fetch_sub (volatile A* obj, M val) noexcept;
T atomic_fetch_sub (A* obj, M val) noexcept;
|
- 将原子对象的封装值减 val,并返回原子对象的旧值(适用于整形和指针类型的 std::atomic 特化版本),整个过程是原子的。
- atomic_fetch_sub_explicit
| template (integral) (1) |
template <class T>
T atomic_fetch_sub_explicit (volatile atomic<T>* obj,
T val, memory_order sync) noexcept;
template <class T>
T atomic_fetch_sub_explicit (atomic<T>* obj,
T val, memory_order sync) noexcept;
|
| template (pointer) (2) |
template <class U>
U* atomic_fetch_sub_explicit (volatile atomic<U*>* obj,
ptrdiff_t val, memory_order sync) noexcept;
template <class U>
U* atomic_fetch_sub_explicit (atomic<U*>* obj,
ptrdiff_t val, memory_order sync) noexcept;
|
| overloads (3) |
T atomic_fetch_sub_explicit (volatile A* obj, M val, memory_order sync) noexcept;
T atomic_fetch_sub_explicit (A* obj, M val, memory_order sync) noexcept;
|
- 将原子对象的封装值减 val,并返回原子对象的旧值(适用于整形和指针类型的 std::atomic 特化版本),整个过程是原子的。
- 该函数等价于 std::atomic 对象的atomic::fetch_sub成员函数。sync 参数指定内存序:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_fetch_and
| emplate (integral) (1) |
template <class T> T atomic_fetch_and (volatile atomic<T>* obj, T val) noexcept;
template <class T> T atomic_fetch_and (atomic<T>* obj, T val) noexcept;
|
| overloads (2) |
T atomic_fetch_and (volatile A* obj, T val) noexcept;
T atomic_fetch_and (A* obj, T val) noexcept;
|
- 将原子对象的封装值按位与 val,并返回原子对象的旧值(只适用于整型的 std::atomic 特化版本),整个过程是原子的。
- atomic_fetch_and_explicit
| template (integral) (1) |
template <class T>
T atomic_fetch_and_explicit (volatile atomic<T>* obj,
T val, memory_order sync) noexcept;
template <class T>
T atomic_fetch_and_explicit (atomic<T>* obj,
T val, memory_order sync) noexcept;
|
| overloads (2) |
T atomic_fetch_and_explicit (volatile A* obj, T val, memory_order sync) noexcept;
T atomic_fetch_and_explicit (A* obj, T val, memory_order sync) noexcept;
|
- 将原子对象的封装值按位与 val,并返回原子对象的旧值(只适用于整型的 std::atomic 特化版本),整个过程是原子的。
- 该函数等价于 std::atomic 对象的atomic::fetch_and成员函数。sync 参数指定内存序:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_fetch_or
| template (integral) (1) |
template <class T> T atomic_fetch_or (volatile atomic<T>* obj, T val) noexcept;
template <class T> T atomic_fetch_or (atomic<T>* obj, T val) noexcept;
|
| overloads (2) |
T atomic_fetch_or (volatile A* obj, T val) noexcept;
T atomic_fetch_or (A* obj, T val) noexcept;
|
- 将原子对象的封装值按位或 val,并返回原子对象的旧值(只适用于整型的 std::atomic 特化版本),整个过程是原子的。
- atomic_fetch_or_explicit
| template (integral) (1) |
template <class T>
T atomic_fetch_or_explicit (volatile atomic<T>* obj,
T val, memory_order sync) noexcept;
template <class T>
T atomic_fetch_or_explicit (atomic<T>* obj,
T val, memory_order sync) noexcept;
|
| overloads (2) |
T atomic_fetch_or_explicit (volatile A* obj, T val, memory_order sync) noexcept;
T atomic_fetch_or_explicit (A* obj, T val, memory_order sync) noexcept;
|
- A将原子对象的封装值按位或 val,并返回原子对象的旧值(只适用于整型的 std::atomic 特化版本),整个过程是原子的。
- 该函数等价于 std::atomic 对象的atomic::fetch_or成员函数。sync 参数指定内存序:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
- atomic_fetch_xor
| template (integral) (1) |
template <class T> T atomic_fetch_xor (volatile atomic<T>* obj, T val) noexcept;
template <class T> T atomic_fetch_xor (atomic<T>* obj, T val) noexcept;
|
| overloads (2) |
T atomic_fetch_xor (volatile A* obj, T val) noexcept;
T atomic_fetch_xor (A* obj, T val) noexcept;
|
- 将原子对象的封装值按位异或 val,并返回原子对象的旧值(只适用于整型的 std::atomic 特化版本),整个过程是原子的。
- atomic_fetch_xor_explicit
| template (integral) (1) |
template <class T>
T atomic_fetch_xor_explicit (volatile atomic<T>* obj,
T val, memory_order sync) noexcept;
template <class T>
T atomic_fetch_xor_explicit (atomic<T>* obj,
T val, memory_order sync) noexcept;
|
| overloads (2) |
T atomic_fetch_xor_explicit (volatile A* obj, T val, memory_order sync) noexcept;
T atomic_fetch_xor_explicit (A* obj, T val, memory_order sync) noexcept;
|
- 将原子对象的封装值按位异或 val,并返回原子对象的旧值(只适用于整型的 std::atomic 特化版本),整个过程是原子的。
- 该函数等价于 std::atomic 对象的atomic::fetch_xor成员函数。sync 参数指定内存序:
| Memory Order 值 |
Memory Order 类型 |
| memory_order_relaxed |
Relaxed |
| memory_order_consume |
Consume |
| memory_order_acquire |
Acquire |
| memory_order_release |
Release |
| memory_order_acq_rel |
Acquire/Release |
| memory_order_seq_cst |
Sequentially consistent |
与原子对象初始化相关的宏
- 此外,还有两个宏值得关注,他们分别是:
- ATOMIC_VAR_INIT(val)
- 初始化 std::atomic 对象。
- ATOMIC_FLAG_INIT
- 初始化 std::atomic_flag 对象。
- C++11 并发指南六(atomic 类型详解三 std::atomic (续))
C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...
- C++11 并发指南六( <atomic> 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)
C++11 并发指南已经写了 5 章,前五章重点介绍了多线程编程方面的内容,但大部分内容只涉及多线程.互斥量.条件变量和异步编程相关的 API,C++11 程序员完全可以不必知道这些 API 在底层是 ...
- 【C/C++开发】C++11 并发指南三(std::mutex 详解)
本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...
- C++11 并发指南五(std::condition_variable 详解)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
- C++11 并发指南五(std::condition_variable 详解)(转)
前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...
- 【转】C++11 并发指南五(std::condition_variable 详解)
http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三 ...
- C++11 并发指南三(std::mutex 详解)
上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex ...
- C++11 并发指南三(std::mutex 详解)(转)
转自:http://www.cnblogs.com/haippy/p/3237213.html 上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::th ...
随机推荐
- css3颜色
镂空字的2种做法
- Windows程序设计(第五版)学习:第二章 Unicode简介
第二章 Unicode简介 1,Windows通过双字节技术DBCS解决这个问题,代码页定义不同的字符集,称为ANSI字符集,比如日文为CP932,韩文为CP949,繁体中文为CP950,简体中文为C ...
- 【软件工程】电梯调度的初步实现 李亚文&&郭莉莉
一.开门见山,代码粘 using System; using System.Collections.Generic; using System.Data; using System.Drawing; ...
- ORACLE 10进制与16进制的互相转换
1. 10---->16 使用to_char(10,'xxx')函数,如果位数长,多加几个 x 2. 16---->10 使用to_number(’a','xxx')函数,如果位数长,多加 ...
- IOS-Appium 自动化测试——环境配置及模拟器、真机跑测试
在MAC环境下配置IOS的appium的自动化测试环境,主要包含三个部分: 一.环境配置 1.安装homebrew(homebrew可以提供MAC OS无法提供的很多套件) ruby -e " ...
- Xml文件操作的其中一个使用方法:
XmlNodeList students = doc.DocumentElement.ChildNodes;//Student节点集合 foreach (XmlNode stu in students ...
- sqlserver 分区表
我们知道很多事情都存在一个分治的思想,同样的道理我们也可以用到数据表上,当一个表很大很大的时候,我们就会想到将表拆 分成很多小表,查询的时候就到各个小表去查,最后进行汇总返回给调用方来加速我们的查询速 ...
- Python.Scrapy.14-scrapy-source-code-analysis-part-4
Scrapy 源代码分析系列-4 scrapy.commands 子包 子包scrapy.commands定义了在命令scrapy中使用的子命令(subcommand): bench, check, ...
- RNN and LSTM saliency Predection Scene Label
http://handong1587.github.io/deep_learning/2015/10/09/rnn-and-lstm.html //RNN and LSTM http://hando ...
- QEMU中smp,socket,cores,threads几个参数的理解
在用QEMU创建KVM guest的时候,为了指定guest cpu资源,用到了-smp, -sockets, -cores, -threads几个参数, #/usr/bin/qemu-system- ...