命名空間
變體
動作

std::atomic

出自 cppreference.com
< cpp‎ | atomic
 
 
並行支援函式庫
執行緒
(C++11)
(C++20)
this_thread 命名空間
(C++11)
(C++11)
(C++11)
協作式取消
互斥 (Mutual exclusion)
(C++11)
通用鎖管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
條件變數
(C++11)
旗標 (Semaphores)
閂鎖 (Latches) 與屏障 (Barriers)
(C++20)
(C++20)
期約 (Futures)
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
風險指標 (Hazard Pointers)
原子型別
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 起)
定義於標頭檔 <stdatomic.h>
#define _Atomic(T) /* 見下文 */
(5) (自 C++23 起)

std::atomic 樣板的每個實體化和全特化都定義了一個原子型別。如果一個執行緒寫入原子物件而另一個執行緒從中讀取,其行為是定義明確的(詳見記憶體模型中關於資料競爭的細節)。

此外,對原子物件的存取可以建立執行緒間同步,並依照 std::memory_order 指定的方式排序非原子記憶體存取。

std::atomic 既不可複製(copyable)也不可移動(movable)。

<stdatomic.h> 中提供了相容性巨集 _Atomic,使得 _Atomic(T)std::atomic<T> 相同,且兩者皆為良構(well-formed)。

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

(自 C++23 起)

目錄

[編輯] 特化

[編輯] 主樣板

std::atomic 樣板可以用任何同時滿足 可複製建構可複製賦值可平凡複製 型別 T 來實體化。如果以下任何值為 false,則程式為非良構(ill-formed):

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_t 以及 wchar_t
  • 標準有號整數型別:signed charshortintlong 以及 long long
  • 標準無號整數型別:unsigned charunsigned shortunsigned intunsigned long 以及 unsigned long long
  • 標頭檔 <cstdint> 中的型別定義(typedefs)所需的任何額外整數型別。

此外,產生的 std::atomic<Integral> 特化具有標準佈局、平凡預設建構子、(直到 C++20)及平凡解構子。有號整數算術定義為使用二補數;不會產生未定義的結果。

浮點數型別的特化

當使用任一無 cv 修飾(cv-unqualified)的浮點數型別(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 的部分特化中。

[編輯] 成員函式

建構原子物件
(公開成員函式) [編輯]
將值儲存到原子物件中
(公開成員函式) [編輯]
檢查原子物件是否為無鎖(lock-free)
(公開成員函式) [編輯]
以原子方式用非原子引數取代原子物件的值
(公開成員函式) [編輯]
以原子方式取得原子物件的值
(公開成員函式) [編輯]
從原子物件中載入值
(公開成員函式) [編輯]
以原子方式取代原子物件的值並取得先前持有的值
(公開成員函式) [編輯]
以原子方式將原子物件的值與非原子引數進行比較,如果相等則執行原子交換,如果不等則執行原子載入
(公開成員函式) [編輯]
(C++20)
阻塞執行緒直到收到通知且原子值發生變化
(公開成員函式) [編輯]
通知至少一個在該原子物件上等待的執行緒
(公開成員函式) [編輯]
通知所有在該原子物件上阻塞等待的執行緒
(公開成員函式) [編輯]

常數

[靜態] (C++17)
指示該型別是否總為無鎖
(公開靜態成員常數) [編輯]

[編輯] 特化的成員函式

針對整數、浮點數(自 C++20 起)及指標型別的特化
以原子方式將引數加到原子物件中存儲的值,並取得先前持有的值
(公開成員函式) [編輯]
以原子方式從原子物件中存儲的值減去引數,並取得先前持有的值
(公開成員函式) [編輯]
對原子值進行加法或減法
(公開成員函式) [編輯]
僅針對整數及指標型別的特化
(C++26)
以原子方式在引數與原子物件的值之間執行 std::max 並取得先前持有的值
(公開成員函式) [編輯]
(C++26)
以原子方式在引數與原子物件的值之間執行 std::min 並取得先前持有的值
(公開成員函式) [編輯]
將原子值遞增或遞減一
(公開成員函式) [編輯]
僅針對整數型別的特化
以原子方式在引數與原子物件的值之間執行位元 AND 並取得先前持有的值
(公開成員函式) [編輯]
以原子方式在引數與原子物件的值之間執行位元 OR 並取得先前持有的值
(公開成員函式) [編輯]
以原子方式在引數與原子物件的值之間執行位元 XOR 並取得先前持有的值
(公開成員函式) [編輯]
對原子值執行位元 AND、OR、XOR
(公開成員函式) [編輯]

[編輯] 型別別名

bool 及上述所有整數型別提供型別別名,如下所示:

所有 std::atomic<Integral> 的別名
atomic_bool
(C++11)
std::atomic<bool>
(型別定義) [編輯]
atomic_char
(C++11)
std::atomic<char>
(型別定義) [編輯]
atomic_schar
(C++11)
std::atomic<signed char>
(型別定義) [編輯]
atomic_uchar
(C++11)
std::atomic<unsigned char>
(型別定義) [編輯]
atomic_short
(C++11)
std::atomic<short>
(型別定義) [編輯]
atomic_ushort
(C++11)
std::atomic<unsigned short>
(型別定義) [編輯]
atomic_int
(C++11)
std::atomic<int>
(型別定義) [編輯]
atomic_uint
(C++11)
std::atomic<unsigned int>
(型別定義) [編輯]
atomic_long
(C++11)
std::atomic<long>
(型別定義) [編輯]
atomic_ulong
(C++11)
std::atomic<unsigned long>
(型別定義) [編輯]
atomic_llong
(C++11)
std::atomic<long long>
(型別定義) [編輯]
atomic_ullong
(C++11)
std::atomic<unsigned long long>
(型別定義) [編輯]
atomic_char8_t
(C++20)
std::atomic<char8_t>
(型別定義) [編輯]
atomic_char16_t
(C++11)
std::atomic<char16_t>
(型別定義) [編輯]
atomic_char32_t
(C++11)
std::atomic<char32_t>
(型別定義) [編輯]
atomic_wchar_t
(C++11)
std::atomic<wchar_t>
(型別定義) [編輯]
atomic_int8_t
(C++11)(選用)
std::atomic<std::int8_t>
(型別定義) [編輯]
atomic_uint8_t
(C++11)(選用)
std::atomic<std::uint8_t>
(型別定義) [編輯]
atomic_int16_t
(C++11)(選用)
std::atomic<std::int16_t>
(型別定義) [編輯]
atomic_uint16_t
(C++11)(選用)
std::atomic<std::uint16_t>
(型別定義) [編輯]
atomic_int32_t
(C++11)(選用)
std::atomic<std::int32_t>
(型別定義) [編輯]
atomic_uint32_t
(C++11)(選用)
std::atomic<std::uint32_t>
(型別定義) [編輯]
atomic_int64_t
(C++11)(選用)
std::atomic<std::int64_t>
(型別定義) [編輯]
atomic_uint64_t
(C++11)(選用)
std::atomic<std::uint64_t>
(型別定義) [編輯]
atomic_int_least8_t
(C++11)
std::atomic<std::int_least8_t>
(型別定義) [編輯]
atomic_uint_least8_t
(C++11)
std::atomic<std::uint_least8_t>
(型別定義) [編輯]
atomic_int_least16_t
(C++11)
std::atomic<std::int_least16_t>
(型別定義) [編輯]
atomic_uint_least16_t
(C++11)
std::atomic<std::uint_least16_t>
(型別定義) [編輯]
atomic_int_least32_t
(C++11)
std::atomic<std::int_least32_t>
(型別定義) [編輯]
atomic_uint_least32_t
(C++11)
std::atomic<std::uint_least32_t>
(型別定義) [編輯]
atomic_int_least64_t
(C++11)
std::atomic<std::int_least64_t>
(型別定義) [編輯]
atomic_uint_least64_t
(C++11)
std::atomic<std::uint_least64_t>
(型別定義) [編輯]
atomic_int_fast8_t
(C++11)
std::atomic<std::int_fast8_t>
(型別定義) [編輯]
atomic_uint_fast8_t
(C++11)
std::atomic<std::uint_fast8_t>
(型別定義) [編輯]
atomic_int_fast16_t
(C++11)
std::atomic<std::int_fast16_t>
(型別定義) [編輯]
atomic_uint_fast16_t
(C++11)
std::atomic<std::uint_fast16_t>
(型別定義) [編輯]
atomic_int_fast32_t
(C++11)
std::atomic<std::int_fast32_t>
(型別定義) [編輯]
atomic_uint_fast32_t
(C++11)
std::atomic<std::uint_fast32_t>
(型別定義) [編輯]
atomic_int_fast64_t
(C++11)
std::atomic<std::int_fast64_t>
(型別定義) [編輯]
atomic_uint_fast64_t
(C++11)
std::atomic<std::uint_fast64_t>
(型別定義) [編輯]
atomic_intptr_t
(C++11)(選用)
std::atomic<std::intptr_t>
(型別定義) [編輯]
atomic_uintptr_t
(C++11)(選用)
std::atomic<std::uintptr_t>
(型別定義) [編輯]
atomic_size_t
(C++11)
std::atomic<std::size_t>
(型別定義) [編輯]
atomic_ptrdiff_t
(C++11)
std::atomic<std::ptrdiff_t>
(型別定義) [編輯]
atomic_intmax_t
(C++11)
std::atomic<std::intmax_t>
(型別定義) [編輯]
atomic_uintmax_t
(C++11)
std::atomic<std::uintmax_t>
(型別定義) [編輯]
特殊用途型別的別名
atomic_signed_lock_free
(C++20)
一種有號整數原子型別,它是無鎖的,且其等待/通知效率最高
(型別定義) [編輯]
atomic_unsigned_lock_free
(C++20)
一種無號整數原子型別,它是無鎖的,且其等待/通知效率最高
(型別定義) [編輯]
註:std::atomic_intN_tstd::atomic_uintN_tstd::atomic_intptr_tstd::atomic_uintptr_t 分別在定義了 std::intN_tstd::uintN_tstd::intptr_tstd::uintptr_t 的情況下才被定義。

std::atomic_signed_lock_freestd::atomic_unsigned_lock_free 在獨立實作(freestanding implementations)中是選用的。

(自 C++20 起)

[編輯] 註記

std::atomic 的所有成員函式都有對應的非成員函式樣板。對於那些不是 std::atomic 的特化但能保證原子性的型別,這些非成員函式可能會被額外多載。標準函式庫中唯一的此類型別是 std::shared_ptr<U>

_Atomic 是一個關鍵字,用於在 C 語言中提供原子型別

建議實作確保在 C 中 _Atomic(T) 的表示方式與 C++ 中對於每個可能的型別 Tstd::atomic<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++ 標準。

DR 應用於 出版時的行為 正確的行為
LWG 2441 C++11 遺漏了選用型別的原子版本之別名定義
固定寬度整數型別曾遺漏
已新增
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 某些原子型別函式的
樣板引數推導可能會意外失敗;
曾提供無效的指標操作
規格已大幅重寫
新增了成員別名 value_type
difference_type

[編輯] 參閱

無鎖的布林原子型別
(類別) [編輯]
原子共享指標
(類別樣板特化) [編輯]
原子弱指標
(類別樣板特化) [編輯]
關於 原子型別C 語言文件
English Deutsch 日本語 中文(简体) 中文(繁體)