c++ 11 原子操作库 (std::atomic)(三)
atomic 類模板及其針對布爾、整型和指針類型的特化
每個 std::atomic 模板的實例化和全特化定義一個原子類型。若一個線程寫入原子對象,同時另一線程從它讀取,則行為良好定義(數據競爭的細節見內存模型)。
另外,對原子對象的訪問可以建立線程間同步,并按 std::memory_order 所對非原子內存訪問定序。
std::atomic 既不可復制亦不可移動。
令原子值增加或減少一
std::atomic<T>::operator++,++(int),--,--(int)| T operator++() noexcept; | (1) | (僅為 atomic<Integral> 模板特化的成員) (C++11 起) |
| T* operator++() noexcept; | (1) | (僅為 atomic<T*> 模板特化的成員) (C++11 起) |
| T operator++( int ) noexcept; | (2) | (僅為 atomic<Integral> 模板特化的成員) (C++11 起) |
| T* operator++( int ) noexcept; | (2) | (僅為 atomic<T*> 模板特化的成員) (C++11 起) |
| T operator--() noexcept; | (3) | (僅為 atomic<Integral> 模板特化的成員) (C++11 起) |
| T* operator--() noexcept; | (3) | (僅為 atomic<T*> 模板特化的成員) (C++11 起) |
| T operator--( int ) noexcept; | (4) | (僅為 atomic<Integral> 模板特化的成員) (C++11 起) |
| T* operator--( int ) noexcept; | (4) | (僅為 atomic<T*> 模板特化的成員) (C++11 起) |
原子地自增或自減當前值。操作為讀-修改-寫操作。
1) 進行原子前自增。等價于 fetch_add(1)+1 。
2) 進行原子后自增。等價于 fetch_add(1) 。
3) 進行原子前自減。等價于 fetch_sub(1)-1 。
4) 進行原子后自減。等價于 fetch_sub(1) 。
對于有符號整數 (Integral) 類型,算術定義為使用補碼表示。無未定義結果。對于 T* 類型,結果可能為未定義地址,但這些操作不會另有未定義行為。
參數
(無)
返回值
1,3) 修改后的原子變量的值。正式地說, *this 的修改順序中自增/自減值的結果立即前趨于此函數的效果。
2,4) 修改前的原子變量的值。正式地說, *this 的修改順序中值立即前趨于此函數的效果。
注意
不同于大多數前自增和自減運算符,原子類型的前自增和自減運算符不返回被修改對象的引用。它們替而返回存儲值的副本。
?
加、減,或與原子值進行逐位與、或、異或
std::atomic<T>::operator+=,-=,&=,|=,^=僅為 atomic<Integral>(C++11) 與 atomic<Floating>(C++20) 模板特化的成員
| T operator+=( T arg ) noexcept; | ||
| T operator+=( T arg ) volatile noexcept; |
僅為 atomic<T*> 模板特化的成員
| T* operator+=( std::ptrdiff_t arg ) noexcept; | ||
| T* operator+=( std::ptrdiff_t arg ) volatile noexcept; |
僅為 atomic<Integral>(C++11) 與 atomic<Floating>(C++20) 模板特化的成員
| T operator-=( T arg ) noexcept; | ||
| T operator-=( T arg ) volatile noexcept; |
僅為 atomic<T*> 模板特化的成員
| T* operator-=( std::ptrdiff_t arg ) noexcept; | ||
| T* operator-=( std::ptrdiff_t arg ) volatile noexcept; |
僅為 atomic<Integral> 模板特化的成員
| T operator&=( T arg ) noexcept; | ||
| T operator&=( T arg ) volatile noexcept; | ||
| T operator|=( T arg ) noexcept; | ||
| T operator|=( T arg ) volatile noexcept; | ||
| T operator^=( T arg ) noexcept; | ||
| T operator^=( T arg ) volatile noexcept; |
?
原子地以涉及先前值和 arg 的計算結果替換當前值。操作是讀-修改-寫操作。
1) 進行原子加法。等價于 fetch_add(arg) + arg 。
2) 進行原子減法。等價于 fetch_sub(arg) - arg 。
3) 進行原子逐位與。等價于 fetch_and(arg) & arg 。
4) 進行原子逐位或。等價于 fetch_or(arg) | arg 。
5) 進行原子逐位異或。等價于 fetch_xor(arg) ^ arg 。
對于有符號整數 (Integral) 類型,算術定義為使用補碼表示。無未定義結果。
| 對于浮點類型,有影響的浮點環境可能異于調用方線程的浮點環境。操作不必服從對應的 std::numeric_limits 特性,但鼓勵這么做。若結果不是其類型所能表示的值,則結果未指定,但操作不會另有未定義行為。 | (C++20 起) |
對于 T* 類型,結果可能為未定義地址,但操作不會另有未定義行為。若 T 不是對象類型則程序為病式。
參數
| arg | - | 算術運算的參數 |
返回值
返回值(即應用對應二元運算符到 *this 的修改順序中立即前趨于成員對應函數效果的值)
注意
不同于大多數復合賦值運算符,原子類型的復合賦值運算符不返回到其左側運算數的引用。它們替而返回存儲的值的副本。
原子地將參數加到存儲于原子對象的值,并返回先前保有的值
std::atomic<T>::fetch_add?僅為 atomic<Integral>(C++11) 與 atomic<Floating>(C++20) 模板特化的成員
| T fetch_add( T arg, | ||
| T fetch_add( T arg, |
僅為 atomic<T*> 模板特化的成員
| T* fetch_add( std::ptrdiff_t arg, | ||
| T* fetch_add( std::ptrdiff_t arg, |
原子地以值和 arg 的算術加法結果替換當前值。運算是讀修改寫操作。按照 order 的值影響內存。
對于有符號 Integral 類型,定義算術為使用補碼。無未定義結果。
| 對于浮點類型,有影響的浮點環境可能異于調用方線程的浮點環境。操作不必服從對應的 std::numeric_limits 特性,但鼓勵這么做。若結果不是其類型所能表示的值,則結果未指定,但其他情況下操作無未定義行為。 | (C++20 起) |
對于 T* 類型,結果可能為未定義的地址,但其他情況下運算無未定義行為。
參數
| arg | - | 算術加法的另一參數 |
| order | - | 強制的內存順序制約 |
返回值
*this 的修改順序中,立即前趨此函數效應的值。
調用示例
#include <iostream> #include <thread> #include <atomic>std::atomic<long long> data; void do_work() {data.fetch_add(1, std::memory_order_relaxed); }int main() {std::thread th1(do_work);std::thread th2(do_work);std::thread th3(do_work);std::thread th4(do_work);std::thread th5(do_work);th1.join();th2.join();th3.join();th4.join();th5.join();std::cout << "Result:" << data << '\n'; }?
原子地從存儲于原子對象的值減去參數,并獲得先前保有的值
std::atomic<T>::fetch_sub| 僅為 atomic<Integral>(C++11) 與 atomic<Floating>(C++20) 模板特化的成員 | ||||
| T fetch_sub( T arg, | (1) | (2) | ||
| T fetch_sub( T arg, | ||||
| 僅為 atomic<T*> 模板特化的成員 | ||||
| T* fetch_sub( std::ptrdiff_t arg, | ||||
| T* fetch_sub( std::ptrdiff_t arg, |
以值和 arg 的算術減法結果原子地替換當前值。操作是讀修改寫操作。按照 order 的值影響內存。
對于有符號 Integral 類型,定義算術為使用補碼表示。無未定義結果。
| 對于浮點類型,有影響的浮點環境可能異于調用方線程的浮點環境。操作不必服從對應的 std::numeric_limits 特性,但鼓勵這么做。若結果不是其類型所能表示的值,則結果未指定,但操作不會另有未定義行為。 | (C++20 起) |
對于 T* 類型,結果可能是未定義地址,但操作不會另有未定義行為。若 T 不是對象類型則程序為病式。
參數
| arg | - | 算術減法的另一參數 |
| order | - | 強制的內存順序制約 |
返回值
*this 的修改順序中立即前趨此函數效果的值。
原子地進行參數和原子對象的值的逐位與,并獲得先前保有的值
std::atomic<T>::fetch_and| T fetch_and( T arg, | ||
| T fetch_and( T arg, |
原子地以值和 arg 逐位與的結果替換當前值。運算是讀修改寫操作。按照 order 的值影響內存。
參數
| arg | - | 逐位與的另一參數 |
| order | - | 強制的內存順序制約 |
返回值
*this 的修改順序中立即前趨此函數效果的值。
原子地進行參數和原子對象的值的逐位或,并獲得先前保有的值
std::atomic<T>::fetch_or| T fetch_or( T arg, | ||
| T fetch_or( T arg, |
原子地以值和 arg 逐位或的結果替換當前值。運算為讀修改寫操作。按照 order 的值影響內存。
參數
| arg | - | 逐位或的另一參數 |
| order | - | 強制的內存順序制約 |
返回值
*this 的修改順序中立即前趨此函數效果的值。
原子地進行參數和原子對象的值的逐位異或,并獲得先前保有的值
std::atomic<T>::fetch_xor| T fetch_xor( T arg, | ||
| T fetch_xor( T arg, |
原子地以值和 arg 逐位異或的結果替換當前值。運算是讀修改寫操作。按照 order 的值影響內存。
參數
| arg | - | 逐位異或的另一參數 |
| order | - | 強制的內存順序制約 |
返回值
*this 的修改順序中立即前趨此函數效果的值。
總結
以上是生活随笔為你收集整理的c++ 11 原子操作库 (std::atomic)(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《JavaScript》条件运算符
- 下一篇: C++ 并发指南-atomic原子变量使