std::atomic
| 定義於標頭檔案 <atomic> |
||
| template< class T > struct atomic; |
(1) | (C++11 起) |
| template< class U > struct atomic<U*>; |
(2) | (C++11 起) |
| 定義於標頭檔案 <memory> |
||
| template< class U > struct atomic<std::shared_ptr<U>>; |
(3) | (C++20 起) |
| template< class U > struct atomic<std::weak_ptr<U>>; |
(4) | (C++20 起) |
| Defined in header <stdatomic.h> |
||
| #define _Atomic(T) /* 見下文 */ |
(5) | (C++23 起) |
std::atomic 模板的每個例項化和完全特化都定義了一個原子型別。如果一個執行緒寫入一個原子物件,而另一個執行緒從它讀取,則行為是定義良好的(有關資料競爭的詳細資訊,請參見記憶體模型)。
此外,對原子物件的訪問可以建立執行緒間同步並按 std::memory_order 指定的順序訪問非原子記憶體。
std::atomic 既不可複製也不可移動。
|
在 <stdatomic.h> 中提供了相容宏 當包含 <stdatomic.h> 時,名稱空間 |
(C++23 起) |
目錄 |
[編輯] 特化
[編輯] 主模板
主 std::atomic 模板可以使用任何滿足 CopyConstructible 和 CopyAssignable 的 可簡單複製 (TriviallyCopyable) 型別 T 進行例項化。如果以下任何值為 false,則程式是非良構的
- std::is_trivially_copyable<T>::value
- std::is_copy_constructible<T>::value
- std::is_move_constructible<T>::value
- std::is_copy_assignable<T>::value
- std::is_move_assignable<T>::value
- std::is_same<T, typename std::remove_cv<T>::type>::value
struct Counters { int a; int b; }; // user-defined trivially-copyable type std::atomic<Counters> cnt; // specialization for the user-defined type
std::atomic<bool> 使用主模板。它保證是一個標準佈局結構並具有平凡解構函式。
[編輯] 部分特化
標準庫為以下型別的 std::atomic 模板提供了部分特化,這些型別具有主模板不具備的額外屬性
std::atomic<U*>。這些特化具有標準佈局、平凡預設建構函式,(C++20 前)和平凡解構函式。除了為所有原子型別提供的操作之外,這些特化還額外支援適用於指標型別的原子算術操作,例如 fetch_add、fetch_sub。|
3,4) 為 std::shared_ptr 和 std::weak_ptr 提供了部分特化 std::atomic<std::shared_ptr<U>> 和 std::atomic<std::weak_ptr<U>>。
詳見 std::atomic<std::shared_ptr> 和 std::atomic<std::weak_ptr>。 |
(C++20 起) |
[編輯] 整數型別的特化
當例項化為以下整數型別之一時,std::atomic 提供了適用於整數型別的額外原子操作,例如 fetch_add、fetch_sub、fetch_and、fetch_or、fetch_xor
- 字元型別 char、char8_t(C++20 起)、char16_t、char32_t 和 wchar_t;
- 標準有符號整數型別:signed char、short、int、long 和 long long;
- 標準無符號整數型別:unsigned char、unsigned short、unsigned int、unsigned long 和 unsigned long long;
- 標頭檔案 <cstdint> 中的 typedefs 所需的任何其他整數型別。
此外,由此產生的 std::atomic<Integral> 特化具有標準佈局、平凡預設建構函式,(C++20 前)和平凡解構函式。有符號整數算術定義為使用二進位制補碼;沒有未定義的結果。
浮點型別的特化當例項化為無 cv 限定的浮點型別(float、double、long double 以及無 cv 限定的擴充套件浮點型別(C++23 起))時, 此外,由此產生的 即使結果無法在浮點型別中表示,也沒有操作會導致未定義行為。浮點環境可能與呼叫執行緒的浮點環境不同。 |
(C++20 起) |
[編輯] 成員型別
| 型別 | 定義 | ||||
value_type
|
T (無論是否特化) | ||||
difference_type[1] |
|
- ↑
difference_type未在主std::atomic模板或 std::shared_ptr 和 std::weak_ptr 的部分特化中定義。
[編輯] 成員函式
| constructs an atomic object (public member function) | |
| stores a value into an atomic object (public member function) | |
| 檢查原子物件是否為無鎖 (public member function) | |
| 原子地將原子物件的值替換為非原子引數 (public member function) | |
| atomically obtains the value of the atomic object (public member function) | |
| loads a value from an atomic object (public member function) | |
| atomically replaces the value of the atomic object and obtains the value held previously (public member function) | |
| 原子地將原子物件的值與非原子引數進行比較,如果相等則執行原子交換,否則執行原子載入 (public member function) | |
| (C++20) |
阻塞執行緒直到被通知且原子值改變 (public member function) |
| (C++20) |
通知至少一個等待原子物件的執行緒 (public member function) |
| (C++20) |
通知所有被原子物件阻塞的執行緒 (public member function) |
常量 | |
| [static] (C++17) |
指示該型別始終是無鎖的 (public static member constant) |
[編輯] 專用成員函式
針對整數、浮點(C++20 起)和指標型別特化 | |
| 原子地將引數新增到原子物件中儲存的值,並獲取之前持有的值 (public member function) | |
| 原子地從原子物件中儲存的值中減去引數,並獲取之前持有的值 (public member function) | |
| 對原子值進行加減 (public member function) | |
僅針對整數和指標型別特化 | |
| (C++26) |
原子地在引數和原子物件的值之間執行 std::max,並獲取之前持有的值 (public member function) |
| (C++26) |
原子地在引數和原子物件的值之間執行 std::min,並獲取之前持有的值 (public member function) |
| 將原子值遞增或遞減一 (public member function) | |
Specialized for integral types only | |
| 原子地在引數和原子物件的值之間執行按位與運算,並獲取之前持有的值 (public member function) | |
| 原子地在引數和原子物件的值之間執行按位或運算,並獲取之前持有的值 (public member function) | |
| 原子地在引數和原子物件的值之間執行按位異或運算,並獲取之前持有的值 (public member function) | |
| 對原子值執行按位與、或、異或運算 (public member function) | |
[編輯] 類型別名
為 bool 和所有上述整數型別提供了類型別名,如下所示
所有
| |
| atomic_bool (C++11) |
std::atomic<bool> (typedef) |
| atomic_char (C++11) |
std::atomic<char> (typedef) |
| atomic_schar (C++11) |
std::atomic<signed char> (typedef) |
| atomic_uchar (C++11) |
std::atomic<unsigned char> (typedef) |
| atomic_short (C++11) |
std::atomic<short> (typedef) |
| atomic_ushort (C++11) |
std::atomic<unsigned short> (typedef) |
| atomic_int (C++11) |
std::atomic<int> (typedef) |
| atomic_uint (C++11) |
std::atomic<unsigned int> (typedef) |
| atomic_long (C++11) |
std::atomic<long> (typedef) |
| atomic_ulong (C++11) |
std::atomic<unsigned long> (typedef) |
| atomic_llong (C++11) |
std::atomic<long long> (typedef) |
| atomic_ullong (C++11) |
std::atomic<unsigned long long> (typedef) |
| atomic_char8_t (C++20) |
std::atomic<char8_t> (typedef) |
| atomic_char16_t (C++11) |
std::atomic<char16_t> (typedef) |
| atomic_char32_t (C++11) |
std::atomic<char32_t> (typedef) |
| atomic_wchar_t (C++11) |
std::atomic<wchar_t> (typedef) |
| atomic_int8_t (C++11)(可選) |
std::atomic<std::int8_t> (typedef) |
| atomic_uint8_t (C++11)(可選) |
std::atomic<std::uint8_t> (typedef) |
| atomic_int16_t (C++11)(可選) |
std::atomic<std::int16_t> (typedef) |
| atomic_uint16_t (C++11)(可選) |
std::atomic<std::uint16_t> (typedef) |
| atomic_int32_t (C++11)(可選) |
std::atomic<std::int32_t> (typedef) |
| atomic_uint32_t (C++11)(可選) |
std::atomic<std::uint32_t> (typedef) |
| atomic_int64_t (C++11)(可選) |
std::atomic<std::int64_t> (typedef) |
| atomic_uint64_t (C++11)(可選) |
std::atomic<std::uint64_t> (typedef) |
| atomic_int_least8_t (C++11) |
std::atomic<std::int_least8_t> (typedef) |
| atomic_uint_least8_t (C++11) |
std::atomic<std::uint_least8_t> (typedef) |
| atomic_int_least16_t (C++11) |
std::atomic<std::int_least16_t> (typedef) |
| atomic_uint_least16_t (C++11) |
std::atomic<std::uint_least16_t> (typedef) |
| atomic_int_least32_t (C++11) |
std::atomic<std::int_least32_t> (typedef) |
| atomic_uint_least32_t (C++11) |
std::atomic<std::uint_least32_t> (typedef) |
| atomic_int_least64_t (C++11) |
std::atomic<std::int_least64_t> (typedef) |
| atomic_uint_least64_t (C++11) |
std::atomic<std::uint_least64_t> (typedef) |
| atomic_int_fast8_t (C++11) |
std::atomic<std::int_fast8_t> (typedef) |
| atomic_uint_fast8_t (C++11) |
std::atomic<std::uint_fast8_t> (typedef) |
| atomic_int_fast16_t (C++11) |
std::atomic<std::int_fast16_t> (typedef) |
| atomic_uint_fast16_t (C++11) |
std::atomic<std::uint_fast16_t> (typedef) |
| atomic_int_fast32_t (C++11) |
std::atomic<std::int_fast32_t> (typedef) |
| atomic_uint_fast32_t (C++11) |
std::atomic<std::uint_fast32_t> (typedef) |
| atomic_int_fast64_t (C++11) |
std::atomic<std::int_fast64_t> (typedef) |
| atomic_uint_fast64_t (C++11) |
std::atomic<std::uint_fast64_t> (typedef) |
| atomic_intptr_t (C++11)(可選) |
std::atomic<std::intptr_t> (typedef) |
| atomic_uintptr_t (C++11)(可選) |
std::atomic<std::uintptr_t> (typedef) |
| atomic_size_t (C++11) |
std::atomic<std::size_t> (typedef) |
| atomic_ptrdiff_t (C++11) |
std::atomic<std::ptrdiff_t> (typedef) |
| atomic_intmax_t (C++11) |
std::atomic<std::intmax_t> (typedef) |
| atomic_uintmax_t (C++11) |
std::atomic<std::uintmax_t> (typedef) |
特殊用途型別的別名 | |
| atomic_signed_lock_free (C++20) |
一個無鎖且等待/通知效率最高的有符號整型原子型別 (typedef) |
| atomic_unsigned_lock_free (C++20) |
一個無鎖且等待/通知效率最高的無符號整型原子型別 (typedef) |
std::intN_t、std::uintN_t、std::intptr_t 和 std::uintptr_t 時,才定義 std::atomic_intN_t、std::atomic_uintN_t、std::atomic_intptr_t 和 std::atomic_uintptr_t。|
|
(C++20 起) |
[編輯] 注意
std::atomic 的所有成員函式都有非成員函式模板等效項。這些非成員函式可以額外過載用於非 std::atomic 特化但能保證原子性的型別。標準庫中唯一的此類型別是 std::shared_ptr<U>。
_Atomic 是一個 關鍵字,用於在 C 中提供 原子型別。
建議實現確保 C 中 _Atomic(T) 的表示形式與 C++ 中 std::atomic<T> 的表示形式對於每種可能的型別 T 都是相同的。用於確保原子性和記憶體順序的機制應相容。
在 GCC 和 Clang 上,這裡描述的一些功能需要連結 -latomic。
| 特性測試宏 | 值 | 標準 | 特性 |
|---|---|---|---|
__cpp_lib_atomic_ref |
201806L |
(C++20) | std::atomic_ref
|
__cpp_lib_constexpr_atomic |
202411L |
(C++26) | constexpr std::atomic 和 std::atomic_ref |
[編輯] 示例
#include <atomic> #include <iostream> #include <thread> #include <vector> std::atomic_int acnt; int cnt; void f() { for (auto n{10000}; n; --n) { ++acnt; ++cnt; // Note: for this example, relaxed memory order is sufficient, // e.g. acnt.fetch_add(1, std::memory_order_relaxed); } } int main() { { std::vector<std::jthread> pool; for (int n = 0; n < 10; ++n) pool.emplace_back(f); } std::cout << "The atomic counter is " << acnt << '\n' << "The non-atomic counter is " << cnt << '\n'; }
可能的輸出
The atomic counter is 100000 The non-atomic counter is 69696
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
| 缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
|---|---|---|---|
| LWG 2441 | C++11 | 可選的原子版本的 typedef 固定寬度整型 缺失 |
已新增 |
| LWG 3012 | C++11 | std::atomic<T> 允許用於任何可平凡複製但不可複製的 T |
此類特化被禁止 |
| LWG 3949 | C++17 | 要求 std::atomic<bool> 具有 平凡解構函式的措辭在 C++17 中意外刪除 |
已添加回來 |
| LWG 4069 (P3323R1) |
C++11 | 對 cv 限定 T 的支援存在疑問 |
禁止 T 為 cv 限定 |
| P0558R1 | C++11 | 一些函式模板引數推導 對於原子型別可能會意外 失敗;提供了無效的指標操作 |
規範被大幅重寫 添加了成員 typedef value_type和 difference_type |
[編輯] 另請參閱
| (C++11) |
無鎖布林原子型別 (類) |
| (C++20) |
原子共享指標 (類模板特化) |
| (C++20) |
原子弱指標 (類模板特化) |
| C 文件 關於 原子型別
| |