C++11同時ガイド6(atomicタイプ詳細3 std::atomic(続き))

7939 ワード

C++11同時ガイド6(<atomic>タイプ詳細2 std::atomic)は基本的な原子型std::atomicの使い方を紹介しています.この節では、C++11標準ライブラリのstd::atomicが整形(integral)とポインタ型の特化バージョンについてどのような改善をしたかを紹介します.
総じて、C++11標準ライブラリのstd::atomicは整形(integral)とポインタタイプの特化バージョンに対していくつかの算術演算と論理演算操作を追加した.具体的には以下の通りです.
integral fetch_add(integral, memory_order = memory_order_seq_cst) volatile;
integral fetch_add(integral, memory_order = memory_order_seq_cst);
integral fetch_sub(integral, memory_order = memory_order_seq_cst) volatile;
integral fetch_sub(integral, memory_order = memory_order_seq_cst);
integral fetch_and(integral, memory_order = memory_order_seq_cst) volatile;
integral fetch_and(integral, memory_order = memory_order_seq_cst);
integral fetch_or(integral, memory_order = memory_order_seq_cst) volatile;
integral fetch_or(integral, memory_order = memory_order_seq_cst);
integral fetch_xor(integral, memory_order = memory_order_seq_cst) volatile;
integral fetch_xor(integral, memory_order = memory_order_seq_cst);

integral operator++(int) volatile;
integral operator++(int);
integral operator--(int) volatile;
integral operator--(int);
integral operator++() volatile;
integral operator++();
integral operator--() volatile;
integral operator--();
integral operator+=(integral) volatile;
integral operator+=(integral);
integral operator-=(integral) volatile;
integral operator-=(integral);
integral operator&=(integral) volatile;
integral operator&=(integral);
integral operator|=(integral) volatile;
integral operator|=(integral);
integral operator^=(integral) volatile;
integral operator^=(integral);

以上のstd::atomic特化バージョンのメンバー関数について簡単に説明します.
fetch_add
if T is integral (1)
T fetch_add (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_add (T val, memory_order sync = memory_order_seq_cst) noexcept;

if T is pointer (2)
T fetch_add (ptrdiff_t val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_add (ptrdiff_t val, memory_order sync = memory_order_seq_cst) noexcept;

原子オブジェクトのカプセル化値をvalに加算し、原子オブジェクトの古い値(整形とポインタタイプに適したstd::atomic特化バージョン)を返します.プロセス全体が原子です.syncパラメータはメモリシーケンスを指定します.
Memory Order値
Memory Orderタイプ
memory_order_relaxed
Relaxed
memory_order_consume
Consume
memory_order_acquire
Acquire
memory_order_release
Release
memory_order_acq_rel
Acquire/Release
memory_order_seq_cst
Sequentially consistent
また、2番目のパラメータが指定されていない場合(デフォルトパラメータmemory_order_seq_cstを取る)、fetch_addはstd::atomic::operator+=に相当します.
fetch_sub
if T is integral (1)
T fetch_sub (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_sub (T val, memory_order sync = memory_order_seq_cst) noexcept;

if T is pointer (2)
T fetch_sub (ptrdiff_t val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_sub (ptrdiff_t val, memory_order sync = memory_order_seq_cst) noexcept;

原子オブジェクトのカプセル化値をvalから減算し、原子オブジェクトの古い値(整形とポインタタイプに適したstd::atomic特化バージョン)を返します.プロセス全体が原子です.syncパラメータはメモリシーケンスを指定します.
Memory Order値
Memory Orderタイプ
memory_order_relaxed
Relaxed
memory_order_consume
Consume
memory_order_acquire
Acquire
memory_order_release
Release
memory_order_acq_rel
Acquire/Release
memory_order_seq_cst
Sequentially consistent
また、2番目のパラメータが指定されていない場合(デフォルトパラメータmemory_order_seq_cstを取る)、fetch_subはstd::atomic::operator-=に相当します.
fetch_and
T fetch_and (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_and (T val, memory_order sync = memory_order_seq_cst) noexcept;

 
原子オブジェクトのカプセル化値をvalとビット別にし、原子オブジェクトの古い値(整数のstd::atomic特化バージョンにのみ適用)を返します.プロセス全体が原子です.syncパラメータはメモリシーケンスを指定します.
Memory Order値
Memory Orderタイプ
memory_order_relaxed
Relaxed
memory_order_consume
Consume
memory_order_acquire
Acquire
memory_order_release
Release
memory_order_acq_rel
Acquire/Release
memory_order_seq_cst
Sequentially consistent
また、2番目のパラメータが指定されていない場合(デフォルトパラメータmemory_order_seq_cstを取る)、fetch_addはstd::atomic::operator&=に相当します.
fetch_or
T fetch_or (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_or (T val, memory_order sync = memory_order_seq_cst) noexcept;

 
原子オブジェクトのカプセル化値をビットまたはvalで指定し、原子オブジェクトの古い値(整数のstd::atomic特化バージョンにのみ適用)を返します.プロセス全体が原子です.syncパラメータはメモリシーケンスを指定します.
Memory Order値
Memory Orderタイプ
memory_order_relaxed
Relaxed
memory_order_consume
Consume
memory_order_acquire
Acquire
memory_order_release
Release
memory_order_acq_rel
Acquire/Release
memory_order_seq_cst
Sequentially consistent
また、2番目のパラメータが指定されていない場合(デフォルトパラメータmemory_order_seq_cstを取る)、fetch_or相当std::atomic::operator|=.
fetch_xor
T fetch_xor (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T fetch_xor (T val, memory_order sync = memory_order_seq_cst) noexcept;

原子オブジェクトのカプセル化値をビット異またはvalで指定し、原子オブジェクトの古い値(整数のstd::atomic特化バージョンにのみ適用)を返します.プロセス全体が原子です.syncパラメータはメモリシーケンスを指定します.
Memory Order値
Memory Orderタイプ
memory_order_relaxed
Relaxed
memory_order_consume
Consume
memory_order_acquire
Acquire
memory_order_release
Release
memory_order_acq_rel
Acquire/Release
memory_order_seq_cst
Sequentially consistent
また、2番目のパラメータが指定されていない場合(デフォルトパラメータmemory_order_seq_cstを取る)、fetch_xorはstd::atomic::operator^=.
operator++
pre-increment (1)
T operator++() volatile noexcept;
T operator++() noexcept;

post-increment (2)
T operator++ (int) volatile noexcept;
T operator++ (int) noexcept;

自己増分演算子はリロードされ、第1の形式(1)は自己増分後の値(すなわち接頭辞+)を返し、第2の形式(2)は自己増分前の値(すなわち接尾辞++)を返し、整形とポインタタイプのstd::atomic特化バージョンに適用される.
operator--
自己減算演算子は再ロードされ、第1の形式(1)は自己減算後の値(すなわち接頭辞--)、第2の形式(2)は自己減算前の値(すなわち接尾辞--)を返し、整形およびポインタタイプのstd::atomic特化バージョンに適用される.
atomic::operator (comp. assign.)
複合代入演算子は、主に次の形式で再ロードされます.
if T is integral (1)
T operator+= (T val) volatile noexcept;
T operator+= (T val) noexcept;
T operator-= (T val) volatile noexcept;
T operator-= (T val) noexcept;
T operator&= (T val) volatile noexcept;
T operator&= (T val) noexcept;
T operator|= (T val) volatile noexcept;
T operator|= (T val) noexcept;
T operator^= (T val) volatile noexcept;
T operator^= (T val) noexcept;

if T is pointer (2)
T operator+= (ptrdiff_t val) volatile noexcept;
T operator+= (ptrdiff_t val) noexcept;
T operator-= (ptrdiff_t val) volatile noexcept;
T operator-= (ptrdiff_t val) noexcept;

以上の各operatorには対応するfetch_*があります.操作、詳細は次の表を参照してください.
オペレータ
メンバー関数
サポートタイプ
ふくごうわりあて
に等しい
せいけい
ポインタタイプ
その他のタイプ+
atomic::operator+=
atomic::fetch_add
はい
はい
いいえ-
atomic::operator-=
atomic::fetch_sub
はい
はい
いいえ&
atomic::operator&=
atomic::fetch_and
はい
いいえ
いいえ|
atomic::operator|=
atomic::fetch_or
はい
いいえ
いいえ^
atomic::operator^=
atomic::fetch_xor
はい
いいえ
いいえ
さて、この節ではまずここを紹介し、次の節ではC++11のCスタイルの原子操作APIを紹介します.