std::atomic_fetch_sub, std::atomic_fetch_sub_explicit
<atomic>
T atomic_fetch_sub( std::atomic <T>* obj,
T atomic_fetch_sub( volatile std::atomic <T>* obj,
T atomic_fetch_sub_explicit( std::atomic <T>* obj,
typename std::atomic <T>::difference_type arg,
T atomic_fetch_sub_explicit( volatile std::atomic <T>* obj,
typename std::atomic <T>::difference_type arg,
Performs atomic subtraction. Atomically subtracts arg from the value pointed to by obj and returns the value obj held previously. The operation is performed as if the following was executed:
If std::atomic<T>
has no fetch_sub
member (this member is only provided for integral , floating-point (since C++20) and pointer types except bool), the program is ill-formed.
[edit] Parameters
[edit] Return value
The value immediately preceding the effects of this function in the modification order of *obj.
[edit] Example
Multiple threads may use std::atomic_fetch_sub
to concurrently process an indexed container.
#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(); }
Output:
reader 2 processed item 50 reader 1 processed item 44 reader 4 processed item 46 <....> reader 0 done reader 4 done reader 3 done
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
P0558R1 | C++11 | exact type match was required becauseT was deduced from multiple arguments
|
T is only deducedfrom obj |
[edit] See also
(public member function of
std::atomic<T>
) [edit]
(function template) [edit]