鍍金池/ 教程/ C/ D.3 <atomic>頭文件
3.4 本章總結(jié)
6.3 基于鎖設(shè)計(jì)更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
6.1 為并發(fā)設(shè)計(jì)的意義何在?
5.2 <code>C++</code>中的原子操作和原子類型
A.7 自動(dòng)推導(dǎo)變量類型
2.1 線程管理的基礎(chǔ)
8.5 在實(shí)踐中設(shè)計(jì)并發(fā)代碼
2.4 運(yùn)行時(shí)決定線程數(shù)量
2.2 向線程函數(shù)傳遞參數(shù)
第4章 同步并發(fā)操作
2.3 轉(zhuǎn)移線程所有權(quán)
8.3 為多線程性能設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)
6.4 本章總結(jié)
7.3 對(duì)于設(shè)計(jì)無鎖數(shù)據(jù)結(jié)構(gòu)的指導(dǎo)建議
關(guān)于這本書
A.1 右值引用
2.6 本章總結(jié)
D.2 &lt;condition_variable&gt;頭文件
A.6 變參模板
6.2 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)
4.5 本章總結(jié)
A.9 本章總結(jié)
前言
第10章 多線程程序的測試和調(diào)試
5.4 本章總結(jié)
第9章 高級(jí)線程管理
5.1 內(nèi)存模型基礎(chǔ)
2.5 識(shí)別線程
第1章 你好,C++的并發(fā)世界!
1.2 為什么使用并發(fā)?
A.5 Lambda函數(shù)
第2章 線程管理
4.3 限定等待時(shí)間
D.3 &lt;atomic&gt;頭文件
10.2 定位并發(fā)錯(cuò)誤的技術(shù)
附錄B 并發(fā)庫的簡單比較
5.3 同步操作和強(qiáng)制排序
A.8 線程本地變量
第8章 并發(fā)代碼設(shè)計(jì)
3.3 保護(hù)共享數(shù)據(jù)的替代設(shè)施
附錄D C++線程庫參考
第7章 無鎖并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
D.7 &lt;thread&gt;頭文件
D.1 &lt;chrono&gt;頭文件
4.1 等待一個(gè)事件或其他條件
A.3 默認(rèn)函數(shù)
附錄A 對(duì)<code>C++</code>11語言特性的簡要介紹
第6章 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
封面圖片介紹
7.2 無鎖數(shù)據(jù)結(jié)構(gòu)的例子
8.6 本章總結(jié)
8.1 線程間劃分工作的技術(shù)
4.2 使用期望等待一次性事件
8.4 設(shè)計(jì)并發(fā)代碼的注意事項(xiàng)
D.5 &lt;mutex&gt;頭文件
3.1 共享數(shù)據(jù)帶來的問題
資源
9.3 本章總結(jié)
10.3 本章總結(jié)
10.1 與并發(fā)相關(guān)的錯(cuò)誤類型
D.4 &lt;future&gt;頭文件
3.2 使用互斥量保護(hù)共享數(shù)據(jù)
9.1 線程池
1.1 何謂并發(fā)
9.2 中斷線程
4.4 使用同步操作簡化代碼
A.2 刪除函數(shù)
1.3 C++中的并發(fā)和多線程
1.4 開始入門
第5章 C++內(nèi)存模型和原子類型操作
消息傳遞框架與完整的ATM示例
8.2 影響并發(fā)代碼性能的因素
7.1 定義和意義
D.6 &lt;ratio&gt;頭文件
A.4 常量表達(dá)式函數(shù)
7.4 本章總結(jié)
1.5 本章總結(jié)
第3章 線程間共享數(shù)據(jù)

D.3 &lt;atomic&gt;頭文件

<atomic>頭文件提供一組基礎(chǔ)的原子類型,和提供對(duì)這些基本類型的操作,以及一個(gè)原子模板函數(shù),用來接收用戶定義的類型,以適用于某些標(biāo)準(zhǔn)。

頭文件內(nèi)容

#define ATOMIC_BOOL_LOCK_FREE 參見詳述
#define ATOMIC_CHAR_LOCK_FREE 參見詳述
#define ATOMIC_SHORT_LOCK_FREE 參見詳述
#define ATOMIC_INT_LOCK_FREE 參見詳述
#define ATOMIC_LONG_LOCK_FREE 參見詳述
#define ATOMIC_LLONG_LOCK_FREE 參見詳述
#define ATOMIC_CHAR16_T_LOCK_FREE 參見詳述
#define ATOMIC_CHAR32_T_LOCK_FREE 參見詳述
#define ATOMIC_WCHAR_T_LOCK_FREE 參見詳述
#define ATOMIC_POINTER_LOCK_FREE 參見詳述

#define ATOMIC_VAR_INIT(value) 參見詳述

namespace std
{
  enum memory_order;

  struct atomic_flag;
  參見類型定義詳述 atomic_bool;
  參見類型定義詳述 atomic_char;
  參見類型定義詳述 atomic_char16_t;
  參見類型定義詳述 atomic_char32_t;
  參見類型定義詳述 atomic_schar;
  參見類型定義詳述 atomic_uchar;
  參見類型定義詳述 atomic_short;
  參見類型定義詳述 atomic_ushort;
  參見類型定義詳述 atomic_int;
  參見類型定義詳述 atomic_uint;
  參見類型定義詳述 atomic_long;
  參見類型定義詳述 atomic_ulong;
  參見類型定義詳述 atomic_llong;
  參見類型定義詳述 atomic_ullong;
  參見類型定義詳述 atomic_wchar_t;

  參見類型定義詳述 atomic_int_least8_t;
  參見類型定義詳述 atomic_uint_least8_t;
  參見類型定義詳述 atomic_int_least16_t;
  參見類型定義詳述 atomic_uint_least16_t;
  參見類型定義詳述 atomic_int_least32_t;
  參見類型定義詳述 atomic_uint_least32_t;
  參見類型定義詳述 atomic_int_least64_t;
  參見類型定義詳述 atomic_uint_least64_t;
  參見類型定義詳述 atomic_int_fast8_t;
  參見類型定義詳述 atomic_uint_fast8_t;
  參見類型定義詳述 atomic_int_fast16_t;
  參見類型定義詳述 atomic_uint_fast16_t;
  參見類型定義詳述 atomic_int_fast32_t;
  參見類型定義詳述 atomic_uint_fast32_t;
  參見類型定義詳述 atomic_int_fast64_t;
  參見類型定義詳述 atomic_uint_fast64_t;
  參見類型定義詳述 atomic_int8_t;
  參見類型定義詳述 atomic_uint8_t;
  參見類型定義詳述 atomic_int16_t;
  參見類型定義詳述 atomic_uint16_t;
  參見類型定義詳述 atomic_int32_t;
  參見類型定義詳述 atomic_uint32_t;
  參見類型定義詳述 atomic_int64_t;
  參見類型定義詳述 atomic_uint64_t;
  參見類型定義詳述 atomic_intptr_t;
  參見類型定義詳述 atomic_uintptr_t;
  參見類型定義詳述 atomic_size_t;
  參見類型定義詳述 atomic_ssize_t;
  參見類型定義詳述 atomic_ptrdiff_t;
  參見類型定義詳述 atomic_intmax_t;
  參見類型定義詳述 atomic_uintmax_t;

  template<typename T>
  struct atomic;

  extern "C" void atomic_thread_fence(memory_order order);
  extern "C" void atomic_signal_fence(memory_order order);

  template<typename T>
  T kill_dependency(T);
}

std::atomic_xxx類型定義

為了兼容新的C標(biāo)準(zhǔn)(C11),C++支持定義原子整型類型。這些類型都與std::atimic<T>;特化類相對(duì)應(yīng),或是用同一接口特化的一個(gè)基本類型。

Table D.1 原子類型定義和與之相關(guān)的std::atmoic<>特化模板

std::atomic_itype 原子類型 std::atomic<> 相關(guān)特化類
atomic_char std::atomic<char>
atomic_schar std::atomic<signed char>
atomic_uchar std::atomic<unsigned char>
atomic_int std::atomic<int>
atomic_uint std::atomic<unsigned>
atomic_short std::atomic<short>
atomic_ushort std::atomic<unsigned short>
atomic_long std::atomic<long>
atomic_ulong std::atomic<unsigned long>
atomic_llong std::atomic<long long>
atomic_ullong std::atomic<unsigned long long>
atomic_wchar_t std::atomic<wchar_t>
atomic_char16_t std::atomic<char16_t>
atomic_char32_t std::atomic<char32_t>

(譯者注:該表與第5章中的表5.1幾乎一致)

D.3.2 ATOMIC_xxx_LOCK_FREE宏

這里的宏指定了原子類型與其內(nèi)置類型是否是無鎖的。

宏定義

#define ATOMIC_BOOL_LOCK_FREE 參見詳述
#define ATOMIC_CHAR_LOCK_FREE參見詳述
#define ATOMIC_SHORT_LOCK_FREE 參見詳述
#define ATOMIC_INT_LOCK_FREE 參見詳述
#define ATOMIC_LONG_LOCK_FREE 參見詳述
#define ATOMIC_LLONG_LOCK_FREE 參見詳述
#define ATOMIC_CHAR16_T_LOCK_FREE 參見詳述
#define ATOMIC_CHAR32_T_LOCK_FREE 參見詳述
#define ATOMIC_WCHAR_T_LOCK_FREE 參見詳述
#define ATOMIC_POINTER_LOCK_FREE 參見詳述

ATOMIC_xxx_LOCK_FREE的值無非就是0,1,2。0意味著,在對(duì)有無符號(hào)的相關(guān)原子類型操作是有鎖的;1意味著,操作只對(duì)一些特定的類型上鎖,而對(duì)沒有指定的類型不上鎖;2意味著,所有操作都是無鎖的。例如,當(dāng)ATOMIC_INT_LOCK_FREE是2的時(shí)候,在std::atomic&lt;int&gt;std::atomic&lt;unsigned&gt;上的操作始終無鎖。

ATOMIC_POINTER_LOCK_FREE描述了,對(duì)于特化的原子類型指針std::atomic<T*>操作的無鎖特性。

D.3.3 ATOMIC_VAR_INIT宏

ATOMIC_VAR_INIT宏可以通過一個(gè)特定的值來初始化一個(gè)原子變量。

聲明 #define ATOMIC_VAR_INIT(value)參見詳述

宏可以擴(kuò)展成一系列符號(hào),這個(gè)宏可以通過一個(gè)給定值,初始化一個(gè)標(biāo)準(zhǔn)原子類型,表達(dá)式如下所示:

std::atomic<type> x = ATOMIC_VAR_INIT(val);

給定值可以兼容與原子變量相關(guān)的非原子變量,例如:

std::atomic&lt;int> i = ATOMIC_VAR_INIT(42);
std::string s;
std::atomic&lt;std::string*> p = ATOMIC_VAR_INIT(&s);

這樣初始化的變量是非原子的,并且在變量初始化之后,其他線程可以隨意的訪問該變量,這樣可以避免條件競爭和未定義行為的發(fā)生。

D.3.4 std::memory_order枚舉類型

std::memory_order枚舉類型用來表明原子操作的約束順序。

聲明

typedef enum memory_order
{
  memory_order_relaxed,memory_order_consume,
  memory_order_acquire,memory_order_release,
  memory_order_acq_rel,memory_order_seq_cst
} memory_order;

通過標(biāo)記各種內(nèi)存序變量來標(biāo)記操作的順序(詳見第5章,在該章節(jié)中有對(duì)書序約束更加詳盡的介紹)

std::memory_order_relaxed

操作不受任何額外的限制。

std::memory_order_release

對(duì)于指定位置上的內(nèi)存可進(jìn)行釋放操作。因此,與獲取操作讀取同一內(nèi)存位置所存儲(chǔ)的值。

std::memory_order_acquire

操作可以獲取指定內(nèi)存位置上的值。當(dāng)需要存儲(chǔ)的值通過釋放操作寫入時(shí),是與存儲(chǔ)操同步的。

std::memory_order_acq_rel

操作必須是“讀-改-寫”操作,并且其行為需要在std::memory_order_acquirestd::memory_order_release序指定的內(nèi)存位置上進(jìn)行操作。

std::memory_order_seq_cst

操作在全局序上都會(huì)受到約束。還有,當(dāng)為存儲(chǔ)操作時(shí),其行為好比std::memory_order_release操作;當(dāng)為加載操作時(shí),其行為好比std::memory_order_acquire操作;并且,當(dāng)其是一個(gè)“讀-改-寫”操作時(shí),其行為和std::memory_order_acquirestd::memory_order_release類似。對(duì)于所有順序來說,該順序?yàn)槟J(rèn)序。

std::memory_order_consume

對(duì)于指定位置的內(nèi)存進(jìn)行消耗操作(consume operation)。

(譯者注:與memory_order_acquire類似)

D.3.5 std::atomic_thread_fence函數(shù)

std::atomic_thread_fence()會(huì)在代碼中插入“內(nèi)存柵欄”,強(qiáng)制兩個(gè)操作保持內(nèi)存約束順序。

聲明

extern "C" void atomic_thread_fence(std::memory_order order);

效果
插入柵欄的目的是為了保證內(nèi)存序的約束性。

柵欄使用std::memory_order_release, std::memory_order_acq_rel, 或 std::memory_order_seq_cst內(nèi)存序,會(huì)同步與一些內(nèi)存位置上的獲取操作進(jìn)行同步,如果這些獲取操作要獲取一個(gè)已存儲(chǔ)的值(通過原子操作進(jìn)行的存儲(chǔ)),就會(huì)通過柵欄進(jìn)行同步。

釋放操作可對(duì)std::memory_order_acquire, std::memory_order_acq_rel, 或 std::memory_order_seq_cst進(jìn)行柵欄同步,;當(dāng)釋放操作存儲(chǔ)的值,在一個(gè)原子操作之前讀取,那么就會(huì)通過柵欄進(jìn)行同步。

拋出

D.3.6 std::atomic_signal_fence函數(shù)

std::atomic_signal_fence()會(huì)在代碼中插入“內(nèi)存柵欄”,強(qiáng)制兩個(gè)操作保持內(nèi)存約束順序,并且在對(duì)應(yīng)線程上執(zhí)行信號(hào)處理操作。

聲明

extern "C" void atomic_signal_fence(std::memory_order order);

效果
根據(jù)需要的內(nèi)存約束序插入一個(gè)柵欄。除非約束序應(yīng)用于“操作和信號(hào)處理函數(shù)在同一線程”的情況下,否則,這個(gè)操作等價(jià)于std::atomic_thread_fence(order)操作。

拋出

D.3.7 std::atomic_flag類

std::atomic_flag類算是原子標(biāo)識(shí)的骨架。在C++11標(biāo)準(zhǔn)下,只有這個(gè)數(shù)據(jù)類型可以保證是無鎖的(當(dāng)然,更多的原子類型在未來的實(shí)現(xiàn)中將采取無鎖實(shí)現(xiàn))。

對(duì)于一個(gè)std::atomic_flag來說,其狀態(tài)不是set,就是clear。

類型定義

struct atomic_flag
{
  atomic_flag() noexcept = default;
  atomic_flag(const atomic_flag&) = delete;
  atomic_flag& operator=(const atomic_flag&) = delete;
  atomic_flag& operator=(const atomic_flag&) volatile = delete;

  bool test_and_set(memory_order = memory_order_seq_cst) volatile
    noexcept;
  bool test_and_set(memory_order = memory_order_seq_cst) noexcept;
  void clear(memory_order = memory_order_seq_cst) volatile noexcept;
  void clear(memory_order = memory_order_seq_cst) noexcept;
};

bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
bool atomic_flag_test_and_set(atomic_flag*) noexcept;
bool atomic_flag_test_and_set_explicit(
  volatile atomic_flag*, memory_order) noexcept;
bool atomic_flag_test_and_set_explicit(
  atomic_flag*, memory_order) noexcept;
void atomic_flag_clear(volatile atomic_flag*) noexcept;
void atomic_flag_clear(atomic_flag*) noexcept;
void atomic_flag_clear_explicit(
  volatile atomic_flag*, memory_order) noexcept;
void atomic_flag_clear_explicit(
  atomic_flag*, memory_order) noexcept;

#define ATOMIC_FLAG_INIT unspecified

std::atomic_flag 默認(rèn)構(gòu)造函數(shù)

這里未指定默認(rèn)構(gòu)造出來的std::atomic_flag實(shí)例是clear狀態(tài),還是set狀態(tài)。因?yàn)閷?duì)象存儲(chǔ)過程是靜態(tài)的,所以初始化必須是靜態(tài)的。

聲明

std::atomic_flag() noexcept = default;

效果
構(gòu)造一個(gè)新std::atomic_flag對(duì)象,不過未指明狀態(tài)。(薛定諤的貓?)

拋出

std::atomic_flag 使用ATOMIC_FLAG_INIT進(jìn)行初始化

std::atomic_flag實(shí)例可以使用ATOMIC_FLAG_INIT宏進(jìn)行創(chuàng)建,這樣構(gòu)造出來的實(shí)例狀態(tài)為clear。因?yàn)閷?duì)象存儲(chǔ)過程是靜態(tài)的,所以初始化必須是靜態(tài)的。

聲明

#define ATOMIC_FLAG_INIT unspecified

用法

std::atomic_flag flag=ATOMIC_FLAG_INIT;

效果
構(gòu)造一個(gè)新std::atomic_flag對(duì)象,狀態(tài)為clear。

拋出

NOTE: 對(duì)于內(nèi)存位置上的*this,這個(gè)操作屬于“讀-改-寫”操作。

std::atomic_flag::test_and_set 成員函數(shù)

自動(dòng)設(shè)置實(shí)例狀態(tài)標(biāo)識(shí),并且檢查實(shí)例的狀態(tài)標(biāo)識(shí)是否已經(jīng)設(shè)置。

聲明

bool atomic_flag_test_and_set(volatile atomic_flag* flag) noexcept;
bool atomic_flag_test_and_set(atomic_flag* flag) noexcept;

效果

return flag->test_and_set();

std::atomic_flag_test_and_set 非成員函數(shù)

自動(dòng)設(shè)置原子變量的狀態(tài)標(biāo)識(shí),并且檢查原子變量的狀態(tài)標(biāo)識(shí)是否已經(jīng)設(shè)置。

聲明

bool atomic_flag_test_and_set_explicit(
    volatile atomic_flag* flag, memory_order order) noexcept;
bool atomic_flag_test_and_set_explicit(
    atomic_flag* flag, memory_order order) noexcept;

效果

return flag->test_and_set(order);

std::atomic_flag_test_and_set_explicit 非成員函數(shù)

自動(dòng)設(shè)置原子變量的狀態(tài)標(biāo)識(shí),并且檢查原子變量的狀態(tài)標(biāo)識(shí)是否已經(jīng)設(shè)置。

聲明

bool atomic_flag_test_and_set_explicit(
    volatile atomic_flag* flag, memory_order order) noexcept;
bool atomic_flag_test_and_set_explicit(
    atomic_flag* flag, memory_order order) noexcept;

效果

return flag->test_and_set(order);

std::atomic_flag::clear 成員函數(shù)

自動(dòng)清除原子變量的狀態(tài)標(biāo)識(shí)。

聲明

void clear(memory_order order = memory_order_seq_cst) volatile noexcept;
void clear(memory_order order = memory_order_seq_cst) noexcept;

先決條件
支持std::memory_order_relaxed,std::memory_order_releasestd::memory_order_seq_cst中任意一個(gè)。

效果
自動(dòng)清除變量狀態(tài)標(biāo)識(shí)。

拋出

NOTE:對(duì)于內(nèi)存位置上的*this,這個(gè)操作屬于“寫”操作(存儲(chǔ)操作)。

std::atomic_flag_clear 非成員函數(shù)

自動(dòng)清除原子變量的狀態(tài)標(biāo)識(shí)。

聲明

void atomic_flag_clear(volatile atomic_flag* flag) noexcept;
void atomic_flag_clear(atomic_flag* flag) noexcept;

效果

flag->clear();

std::atomic_flag_clear_explicit 非成員函數(shù)

自動(dòng)清除原子變量的狀態(tài)標(biāo)識(shí)。

聲明

void atomic_flag_clear_explicit(
    volatile atomic_flag* flag, memory_order order) noexcept;
void atomic_flag_clear_explicit(
    atomic_flag* flag, memory_order order) noexcept;

效果

return flag->clear(order);

D.3.8 std::atomic類型模板

std::atomic提供了對(duì)任意類型的原子操作的包裝,以滿足下面的需求。

模板參數(shù)BaseType必須滿足下面的條件。

  • 具有簡單的默認(rèn)構(gòu)造函數(shù)
  • 具有簡單的拷貝賦值操作
  • 具有簡單的析構(gòu)函數(shù)
  • 可以進(jìn)行位比較

這就意味著std::atomic&lt;some-simple-struct&gt;會(huì)和使用std::atomic<some-built-in-type>一樣簡單;不過對(duì)于std::atomic<std::string>就不同了。

除了主模板,對(duì)于內(nèi)置整型和指針的特化,模板也支持類似x++這樣的操作。

std::atomic實(shí)例是不支持CopyConstructible(拷貝構(gòu)造)和CopyAssignable(拷貝賦值),原因你懂得,因?yàn)檫@樣原子操作就無法執(zhí)行。

類型定義

template<typename BaseType>
struct atomic
{
  atomic() noexcept = default;
  constexpr atomic(BaseType) noexcept;
  BaseType operator=(BaseType) volatile noexcept;
  BaseType operator=(BaseType) noexcept;

  atomic(const atomic&) = delete;
  atomic& operator=(const atomic&) = delete;
  atomic& operator=(const atomic&) volatile = delete;

  bool is_lock_free() const volatile noexcept;
  bool is_lock_free() const noexcept;

  void store(BaseType,memory_order = memory_order_seq_cst)
      volatile noexcept;
  void store(BaseType,memory_order = memory_order_seq_cst) noexcept;
  BaseType load(memory_order = memory_order_seq_cst)
      const volatile noexcept;
  BaseType load(memory_order = memory_order_seq_cst) const noexcept;
  BaseType exchange(BaseType,memory_order = memory_order_seq_cst)
      volatile noexcept;
  BaseType exchange(BaseType,memory_order = memory_order_seq_cst)
      noexcept;

  bool compare_exchange_strong(
      BaseType & old_value, BaseType new_value,
      memory_order order = memory_order_seq_cst) volatile noexcept;
  bool compare_exchange_strong(
      BaseType & old_value, BaseType new_value,
      memory_order order = memory_order_seq_cst) noexcept;
  bool compare_exchange_strong(
      BaseType & old_value, BaseType new_value,
      memory_order success_order,
      memory_order failure_order) volatile noexcept;
  bool compare_exchange_strong(
      BaseType & old_value, BaseType new_value,
      memory_order success_order,
      memory_order failure_order) noexcept;
  bool compare_exchange_weak(
      BaseType & old_value, BaseType new_value,
      memory_order order = memory_order_seq_cst)
      volatile noexcept;
  bool compare_exchange_weak(
      BaseType & old_value, BaseType new_value,
      memory_order order = memory_order_seq_cst) noexcept;
  bool compare_exchange_weak(
      BaseType & old_value, BaseType new_value,
      memory_order success_order,
      memory_order failure_order) volatile noexcept;
  bool compare_exchange_weak(
      BaseType & old_value, BaseType new_value,
      memory_order success_order,
      memory_order failure_order) noexcept;
      operator BaseType () const volatile noexcept;
      operator BaseType () const noexcept;
};

template<typename BaseType>
bool atomic_is_lock_free(volatile const atomic<BaseType>*) noexcept;
template<typename BaseType>
bool atomic_is_lock_free(const atomic<BaseType>*) noexcept;
template<typename BaseType>
void atomic_init(volatile atomic<BaseType>*, void*) noexcept;
template<typename BaseType>
void atomic_init(atomic<BaseType>*, void*) noexcept;
template<typename BaseType>
BaseType atomic_exchange(volatile atomic<BaseType>*, memory_order)
  noexcept;
template<typename BaseType>
BaseType atomic_exchange(atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_exchange_explicit(
  volatile atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_exchange_explicit(
  atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
void atomic_store(volatile atomic<BaseType>*, BaseType) noexcept;
template<typename BaseType>
void atomic_store(atomic<BaseType>*, BaseType) noexcept;
template<typename BaseType>
void atomic_store_explicit(
  volatile atomic<BaseType>*, BaseType, memory_order) noexcept;
template<typename BaseType>
void atomic_store_explicit(
  atomic<BaseType>*, BaseType, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_load(volatile const atomic<BaseType>*) noexcept;
template<typename BaseType>
BaseType atomic_load(const atomic<BaseType>*) noexcept;
template<typename BaseType>
BaseType atomic_load_explicit(
  volatile const atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
BaseType atomic_load_explicit(
  const atomic<BaseType>*, memory_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong(
  volatile atomic<BaseType>*,BaseType * old_value,
  BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong(
  atomic<BaseType>*,BaseType * old_value,
  BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
  volatile atomic<BaseType>*,BaseType * old_value,
  BaseType new_value, memory_order success_order,
  memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
  atomic<BaseType>*,BaseType * old_value,
  BaseType new_value, memory_order success_order,
  memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak(
  volatile atomic<BaseType>*,BaseType * old_value,BaseType new_value)
  noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak(
  atomic<BaseType>*,BaseType * old_value,BaseType new_value) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
  volatile atomic<BaseType>*,BaseType * old_value,
  BaseType new_value, memory_order success_order,
  memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
  atomic<BaseType>*,BaseType * old_value,
  BaseType new_value, memory_order success_order,
  memory_order failure_order) noexcept;

NOTE:雖然非成員函數(shù)通過模板的方式指定,不過他們只作為從在函數(shù)提供,并且對(duì)于這些函數(shù),不能顯示的指定模板的參數(shù)。

std::atomic 構(gòu)造函數(shù)

使用默認(rèn)初始值,構(gòu)造一個(gè)std::atomic實(shí)例。

聲明

atomic() noexcept;

效果
使用默認(rèn)初始值,構(gòu)造一個(gè)新std::atomic實(shí)例。因?qū)ο笫庆o態(tài)存儲(chǔ)的,所以初始化過程也是靜態(tài)的。

NOTE:當(dāng)std::atomic實(shí)例以非靜態(tài)方式初始化的,那么其值就是不可估計(jì)的。

拋出

std::atomic_init 非成員函數(shù)

std::atomic<BaseType>實(shí)例提供的值,可非原子的進(jìn)行存儲(chǔ)。

聲明

template<typename BaseType>
void atomic_init(atomic<BaseType> volatile* p, BaseType v) noexcept;
template<typename BaseType>
void atomic_init(atomic<BaseType>* p, BaseType v) noexcept;

效果
將值v以非原子存儲(chǔ)的方式,存儲(chǔ)在*p中。調(diào)用atomic<BaseType>實(shí)例中的atomic_init(),這里需要實(shí)例不是默認(rèn)構(gòu)造出來的,或者在構(gòu)造出來的時(shí)候被執(zhí)行了某些操作,否則將會(huì)引發(fā)未定義行為。

NOTE:因?yàn)榇鎯?chǔ)是非原子的,對(duì)對(duì)象指針p任意的并發(fā)訪問(即使是原子操作)都會(huì)引發(fā)數(shù)據(jù)競爭。

拋出

std::atomic 轉(zhuǎn)換構(gòu)造函數(shù)

使用提供的BaseType值去構(gòu)造一個(gè)std::atomic實(shí)例。

聲明

constexpr atomic(BaseType b) noexcept;

效果
通過b值構(gòu)造一個(gè)新的std::atomic對(duì)象。因?qū)ο笫庆o態(tài)存儲(chǔ)的,所以初始化過程也是靜態(tài)的。

拋出

std::atomic 轉(zhuǎn)換賦值操作

在*this存儲(chǔ)一個(gè)新值。

聲明

BaseType operator=(BaseType b) volatile noexcept;
BaseType operator=(BaseType b) noexcept;

效果

return this->store(b);

std::atomic::is_lock_free 成員函數(shù)

確定對(duì)于*this是否是無鎖操作。

聲明

bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;

返回
當(dāng)操作是無鎖操作,那么就返回true,否則返回false。

拋出

std::atomic_is_lock_free 非成員函數(shù)

確定對(duì)于*this是否是無鎖操作。

聲明

template<typename BaseType>
bool atomic_is_lock_free(volatile const atomic<BaseType>* p) noexcept;
template<typename BaseType>
bool atomic_is_lock_free(const atomic<BaseType>* p) noexcept;

效果

return p->is_lock_free();

std::atomic::load 成員函數(shù)

原子的加載std::atomic實(shí)例當(dāng)前的值

聲明

BaseType load(memory_order order = memory_order_seq_cst)
    const volatile noexcept;
BaseType load(memory_order order = memory_order_seq_cst) const noexcept;

先決條件
支持std::memory_order_relaxed、std::memory_order_acquire、std::memory_order_consumestd::memory_order_seq_cst內(nèi)存序。

效果
原子的加載已存儲(chǔ)到*this上的值。

返回
返回存儲(chǔ)在*this上的值。

拋出

NOTE:是對(duì)于*this內(nèi)存地址原子加載的操作。

std::atomic_load 非成員函數(shù)

原子的加載std::atomic實(shí)例當(dāng)前的值。

聲明

template<typename BaseType>
BaseType atomic_load(volatile const atomic<BaseType>* p) noexcept;
template<typename BaseType>
BaseType atomic_load(const atomic<BaseType>* p) noexcept;

效果

return p->load();

std::atomic_load_explicit 非成員函數(shù)

原子的加載std::atomic實(shí)例當(dāng)前的值。

聲明

template<typename BaseType>
BaseType atomic_load_explicit(
    volatile const atomic<BaseType>* p, memory_order order) noexcept;
template<typename BaseType>
BaseType atomic_load_explicit(
    const atomic<BaseType>* p, memory_order order) noexcept;

效果

return p->load(order);

std::atomic::operator BastType轉(zhuǎn)換操作

加載存儲(chǔ)在*this中的值。

聲明

operator BaseType() const volatile noexcept;
operator BaseType() const noexcept;

效果

return this->load();

std::atomic::store 成員函數(shù)

以原子操作的方式存儲(chǔ)一個(gè)新值到atomic<BaseType>實(shí)例中。

聲明

void store(BaseType new_value,memory_order order = memory_order_seq_cst)
    volatile noexcept;
void store(BaseType new_value,memory_order order = memory_order_seq_cst)
    noexcept;

先決條件
支持std::memory_order_relaxedstd::memory_order_releasestd::memory_order_seq_cst內(nèi)存序。

效果
將new_value原子的存儲(chǔ)到*this中。

拋出

NOTE:是對(duì)于*this內(nèi)存地址原子加載的操作。

std::atomic_store 非成員函數(shù)

以原子操作的方式存儲(chǔ)一個(gè)新值到atomic&lt;BaseType&gt;實(shí)例中。

聲明

template<typename BaseType>
void atomic_store(volatile atomic<BaseType>* p, BaseType new_value)
    noexcept;
template<typename BaseType>
void atomic_store(atomic<BaseType>* p, BaseType new_value) noexcept;

效果

p->store(new_value);

std::atomic_explicit 非成員函數(shù)

以原子操作的方式存儲(chǔ)一個(gè)新值到atomic&lt;BaseType&gt;實(shí)例中。

聲明

template<typename BaseType>
void atomic_store_explicit(
    volatile atomic<BaseType>* p, BaseType new_value, memory_order order)
    noexcept;
template<typename BaseType>
void atomic_store_explicit(
    atomic<BaseType>* p, BaseType new_value, memory_order order) noexcept;

效果

p->store(new_value,order);

std::atomic::exchange 成員函數(shù)

原子的存儲(chǔ)一個(gè)新值,并讀取舊值。

聲明

BaseType exchange(
    BaseType new_value,
    memory_order order = memory_order_seq_cst)
    volatile noexcept;

效果
原子的將new_value存儲(chǔ)在this中,并且取出this中已經(jīng)存儲(chǔ)的值。

返回
返回*this之前的值。

拋出

NOTE:這是對(duì)*this內(nèi)存地址的原子“讀-改-寫”操作。

std::atomic_exchange 非成員函數(shù)

原子的存儲(chǔ)一個(gè)新值到atomic<BaseType>實(shí)例中,并且讀取舊值。

聲明

template<typename BaseType>
BaseType atomic_exchange(volatile atomic<BaseType>* p, BaseType new_value)
    noexcept;
template<typename BaseType>
BaseType atomic_exchange(atomic<BaseType>* p, BaseType new_value) noexcept;

效果

return p->exchange(new_value);

std::atomic_exchange_explicit 非成員函數(shù)

原子的存儲(chǔ)一個(gè)新值到atomic<BaseType>實(shí)例中,并且讀取舊值。

聲明

template<typename BaseType>
BaseType atomic_exchange_explicit(
    volatile atomic<BaseType>* p, BaseType new_value, memory_order order)
    noexcept;
template<typename BaseType>
BaseType atomic_exchange_explicit(
    atomic<BaseType>* p, BaseType new_value, memory_order order) noexcept;

效果

return p->exchange(new_value,order);

std::atomic::compare_exchange_strong 成員函數(shù)

當(dāng)期望值和新值一樣時(shí),將新值存儲(chǔ)到實(shí)例中。如果不相等,那么就實(shí)用新值更新期望值。

聲明

bool compare_exchange_strong(
    BaseType& expected,BaseType new_value,
    memory_order order = std::memory_order_seq_cst) volatile noexcept;
bool compare_exchange_strong(
    BaseType& expected,BaseType new_value,
    memory_order order = std::memory_order_seq_cst) noexcept;
bool compare_exchange_strong(
    BaseType& expected,BaseType new_value,
    memory_order success_order,memory_order failure_order)
    volatile noexcept;
bool compare_exchange_strong(
    BaseType& expected,BaseType new_value,
    memory_order success_order,memory_order failure_order) noexcept;

先決條件
failure_order不能是std::memory_order_releasestd::memory_order_acq_rel內(nèi)存序。

效果
將存儲(chǔ)在this中的expected值與new_value值進(jìn)行逐位對(duì)比,當(dāng)相等時(shí)間new_value存儲(chǔ)在this中;否則,更新expected的值。

返回
當(dāng)new_value的值與*this中已經(jīng)存在的值相同,就返回true;否則,返回false。

拋出

NOTE:在success_order==order和failure_order==order的情況下,三個(gè)參數(shù)的重載函數(shù)與四個(gè)參數(shù)的重載函數(shù)等價(jià)。除非,order是std::memory_order_acq_rel時(shí),failure_order是std::memory_order_acquire,且當(dāng)order是std::memory_order_release時(shí),failure_order是std::memory_order_relaxed。

NOTE:當(dāng)返回true和success_order內(nèi)存序時(shí),是對(duì)this內(nèi)存地址的原子“讀-改-寫”操作;反之,這是對(duì)this內(nèi)存地址的原子加載操作(failure_order)。

std::atomic_compare_exchange_strong 非成員函數(shù)

當(dāng)期望值和新值一樣時(shí),將新值存儲(chǔ)到實(shí)例中。如果不相等,那么就實(shí)用新值更新期望值。

聲明

template<typename BaseType>
bool atomic_compare_exchange_strong(
    volatile atomic<BaseType>* p,BaseType * old_value,BaseType new_value)
    noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong(  
    atomic<BaseType>* p,BaseType * old_value,BaseType new_value) noexcept;

效果

return p->compare_exchange_strong(*old_value,new_value);

std::atomic_compare_exchange_strong_explicit 非成員函數(shù)

當(dāng)期望值和新值一樣時(shí),將新值存儲(chǔ)到實(shí)例中。如果不相等,那么就實(shí)用新值更新期望值。

聲明

template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
    volatile atomic<BaseType>* p,BaseType * old_value,
    BaseType new_value, memory_order success_order,
    memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_strong_explicit(
    atomic<BaseType>* p,BaseType * old_value,
    BaseType new_value, memory_order success_order,
    memory_order failure_order) noexcept;

效果

return p->compare_exchange_strong(
    *old_value,new_value,success_order,failure_order) noexcept;

std::atomic::compare_exchange_weak 成員函數(shù)

原子的比較新值和期望值,如果相等,那么存儲(chǔ)新值并且進(jìn)行原子化更新。當(dāng)兩值不相等,或更新未進(jìn)行,那期望值會(huì)更新為新值。

聲明

bool compare_exchange_weak(
    BaseType& expected,BaseType new_value,
    memory_order order = std::memory_order_seq_cst) volatile noexcept;
bool compare_exchange_weak(
    BaseType& expected,BaseType new_value,
    memory_order order = std::memory_order_seq_cst) noexcept;
bool compare_exchange_weak(
    BaseType& expected,BaseType new_value,
    memory_order success_order,memory_order failure_order)
    volatile noexcept;
bool compare_exchange_weak(
    BaseType& expected,BaseType new_value,
    memory_order success_order,memory_order failure_order) noexcept;

先決條件
failure_order不能是std::memory_order_releasestd::memory_order_acq_rel內(nèi)存序。

效果
將存儲(chǔ)在this中的expected值與new_value值進(jìn)行逐位對(duì)比,當(dāng)相等時(shí)間new_value存儲(chǔ)在this中;否則,更新expected的值。

返回
當(dāng)new_value的值與*this中已經(jīng)存在的值相同,就返回true;否則,返回false。

拋出

NOTE:在success_order==order和failure_order==order的情況下,三個(gè)參數(shù)的重載函數(shù)與四個(gè)參數(shù)的重載函數(shù)等價(jià)。除非,order是std::memory_order_acq_rel時(shí),failure_order是std::memory_order_acquire,且當(dāng)order是std::memory_order_release時(shí),failure_order是std::memory_order_relaxed。

NOTE:當(dāng)返回true和success_order內(nèi)存序時(shí),是對(duì)this內(nèi)存地址的原子“讀-改-寫”操作;反之,這是對(duì)this內(nèi)存地址的原子加載操作(failure_order)。

std::atomic_compare_exchange_weak 非成員函數(shù)

原子的比較新值和期望值,如果相等,那么存儲(chǔ)新值并且進(jìn)行原子化更新。當(dāng)兩值不相等,或更新未進(jìn)行,那期望值會(huì)更新為新值。

聲明

template<typename BaseType>
bool atomic_compare_exchange_weak(
    volatile atomic<BaseType>* p,BaseType * old_value,BaseType new_value)
    noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak(
    atomic<BaseType>* p,BaseType * old_value,BaseType new_value) noexcept;

效果

return p->compare_exchange_weak(*old_value,new_value);

std::atomic_compare_exchange_weak_explicit 非成員函數(shù)

原子的比較新值和期望值,如果相等,那么存儲(chǔ)新值并且進(jìn)行原子化更新。當(dāng)兩值不相等,或更新未進(jìn)行,那期望值會(huì)更新為新值。

聲明

template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
    volatile atomic<BaseType>* p,BaseType * old_value,
    BaseType new_value, memory_order success_order,
    memory_order failure_order) noexcept;
template<typename BaseType>
bool atomic_compare_exchange_weak_explicit(
    atomic<BaseType>* p,BaseType * old_value,
    BaseType new_value, memory_order success_order,
    memory_order failure_order) noexcept;

效果

return p->compare_exchange_weak(
   *old_value,new_value,success_order,failure_order);

D.3.9 std::atomic模板類型的特化

std::atomic類模板的特化類型有整型和指針類型。對(duì)于整型來說,特化模板提供原子加減,以及位域操作(主模板未提供)。對(duì)于指針類型來說,特化模板提供原子指針的運(yùn)算(主模板未提供)。

特化模板提供如下整型:

std::atomic<bool>
std::atomic<char>
std::atomic<signed char>
std::atomic<unsigned char>
std::atomic<short>
std::atomic<unsigned short>
std::atomic<int>
std::atomic<unsigned>
std::atomic<long>
std::atomic<unsigned long>
std::atomic<long long>
std::atomic<unsigned long long>
std::atomic<wchar_t>
std::atomic<char16_t>
std::atomic<char32_t&gt;

std::atomic<T*>原子指針,可以使用以上的類型作為T。

D.3.10 特化std::atomic<integral-type>

std::atomic&lt;integral-type&gt;是為每一個(gè)基礎(chǔ)整型提供的std::atomic類模板,其中提供了一套完整的整型操作。

下面的特化模板也適用于std::atomic<>類模板:

std::atomic<char>
std::atomic<signed char>
std::atomic<unsigned char>
std::atomic<short>
std::atomic<unsigned short>
std::atomic<int>
std::atomic<unsigned>
std::atomic<long>
std::atomic<unsigned long>
std::atomic<long long>
std::atomic<unsigned long long>
std::atomic<wchar_t>
std::atomic<char16_t>
std::atomic<char32_t>

因?yàn)樵硬僮髦荒軋?zhí)行其中一個(gè),所以特化模板的實(shí)例不可CopyConstruc