名稱空間
變體
操作

std::atomic

來自 cppreference.com
< cpp‎ | atomic
 
 
併發支援庫
執行緒
(C++11)
(C++20)
this_thread 名稱空間
(C++11)
(C++11)
(C++11)
協同取消
互斥
(C++11)
通用鎖管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
條件變數
(C++11)
訊號量
門閂和屏障
(C++20)
(C++20)
期值
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
危險指標
原子型別
atomic
(C++11)
(C++20)
原子型別的初始化
(C++11)(C++20 中已棄用)
(C++11)(C++20 中已棄用)
記憶體排序
(C++11)(C++26 中已棄用)
原子操作的自由函式
原子標誌的自由函式
 
 
定義於標頭檔案 <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> 中提供了相容宏 _Atomic,使得 _Atomic(T)std::atomic<T> 相同,同時兩者都是良好形成的。

當包含 <stdatomic.h> 時,名稱空間 std 中的任何宣告是否可用是未指定的。

(C++23 起)

目錄

[編輯] 特化

[編輯] 主模板

std::atomic 模板可以使用任何滿足 CopyConstructibleCopyAssignable可簡單複製 (TriviallyCopyable) 型別 T 進行例項化。如果以下任何值為 false,則程式是非良構的

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 模板提供了部分特化,這些型別具有主模板不具備的額外屬性

2) 針對所有指標型別的部分特化 std::atomic<U*>。這些特化具有標準佈局、平凡預設建構函式,(C++20 前)和平凡解構函式。除了為所有原子型別提供的操作之外,這些特化還額外支援適用於指標型別的原子算術操作,例如 fetch_addfetch_sub
3,4)std::shared_ptrstd::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_addfetch_subfetch_andfetch_orfetch_xor

  • 字元型別 charchar8_t(C++20 起)char16_tchar32_twchar_t
  • 標準有符號整數型別:signed charshortintlonglong long
  • 標準無符號整數型別:unsigned charunsigned shortunsigned intunsigned longunsigned long long
  • 標頭檔案 <cstdint> 中的 typedefs 所需的任何其他整數型別。

此外,由此產生的 std::atomic<Integral> 特化具有標準佈局、平凡預設建構函式,(C++20 前)和平凡解構函式。有符號整數算術定義為使用二進位制補碼;沒有未定義的結果。

浮點型別的特化

當例項化為無 cv 限定的浮點型別(floatdoublelong double 以及無 cv 限定的擴充套件浮點型別(C++23 起))時,std::atomic 提供了適用於浮點型別的額外原子操作,例如 fetch_addfetch_sub

此外,由此產生的 std::atomic<Floating> 特化具有標準佈局和平凡解構函式。

即使結果無法在浮點型別中表示,也沒有操作會導致未定義行為。浮點環境可能與呼叫執行緒的浮點環境不同。

(C++20 起)

[編輯] 成員型別

型別 定義
value_type T (無論是否特化)
difference_type[1]

value_type (僅適用於 atomic<Integral>atomic<Floating>(C++20 起) 特化)

std::ptrdiff_t (僅適用於 std::atomic<U*> 特化)

  1. difference_type 未在主 std::atomic 模板或 std::shared_ptrstd::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) [編輯]
通知至少一個等待原子物件的執行緒
(public member function) [編輯]
通知所有被原子物件阻塞的執行緒
(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 和所有上述整數型別提供了類型別名,如下所示

所有 std::atomic<Integral> 的別名
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_tstd::uintN_tstd::intptr_tstd::uintptr_t 時,才定義 std::atomic_intN_tstd::atomic_uintN_tstd::atomic_intptr_tstd::atomic_uintptr_t

std::atomic_signed_lock_freestd::atomic_unsigned_lock_free 在獨立實現中是可選的。

(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::atomicstd::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 文件 關於 原子型別
English 日本語 中文(简体) 中文(繁體)