std::atomic_fetch_sub, std::atomic_fetch_sub_explicit
From cppreference.com
| ヘッダー <atomic> で定義 |
||
| template< class T > T atomic_fetch_sub( std::atomic<T>* obj, |
(1) | (C++11以降) |
| template< class T > T atomic_fetch_sub( volatile std::atomic<T>* obj, |
(2) | (C++11以降) |
| template< class T > T atomic_fetch_sub_explicit( std::atomic<T>* obj, |
(3) | (C++11以降) |
| template< class T > T atomic_fetch_sub_explicit( volatile std::atomic<T>* obj, |
(4) | (C++11以降) |
アトミックな減算を実行します。 obj が指す値から arg をアトミックに減算し、 obj が以前に保持していた値を返します。この操作は、以下が実行されたかのように行われます。
1,2) obj->fetch_sub(arg)
3,4) obj->fetch_sub(arg, order)
std::atomic<T> に fetch_sub メンバがない場合(このメンバは 整数型、 浮動小数点型(C++20以降) および ポインタ型(bool を除く)に対してのみ提供されます)、プログラムは不定形となります。
目次 |
[編集] パラメータ
| obj | - | 操作対象のアトミックオブジェクトへのポインタ |
| arg | - | アトミックオブジェクトに格納されている値から減算する値 |
| order | - | メモリ同期順序 |
[編集] 戻り値
*objの修正順序において、この関数の効果の直前の値。
[編集] 例
複数のスレッドが std::atomic_fetch_sub を使用して、インデックス付きコンテナを同時に処理できます。
このコードを実行
#include <atomic> #include <iostream> #include <numeric> #include <string> #include <thread> #include <vector> const int N = 50; std::atomic<int> cnt; std::vector<int> data(N); void reader(int id) { for (;;) { int idx = atomic_fetch_sub_explicit(&cnt, 1, std::memory_order_relaxed); if (idx >= 0) std::cout << "reader " << std::to_string(id) << " processed item " << std::to_string(data[idx]) << '\n'; else { std::cout << "reader " << std::to_string(id) << " done\n"; break; } } } int main() { std::iota(data.begin(), data.end(), 1); cnt = data.size() - 1; std::vector<std::thread> v; for (int n = 0; n < 5; ++n) v.emplace_back(reader, n); for (auto& t : v) t.join(); }
出力
reader 2 processed item 50 reader 1 processed item 44 reader 4 processed item 46 <....> reader 0 done reader 4 done reader 3 done
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| P0558R1 | C++11 | 厳密な型一致が必要であったためTは複数の引数から推論された |
Tは推論されるのみobj から |
[編集] 関連項目
| 引数をアトミックオブジェクトに格納された値からアトミックに減算し、以前に保持されていた値を取得する ( std::atomic<T> のメンバ関数) | |
| (C++11)(C++11) |
アトミックオブジェクトに非アトミックな値を加算し、アトミックオブジェクトの以前の値を取得する (関数テンプレート) |