|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Defined in header <atomic> | ||
template<class T> T atomic_fetch_sub(std::atomic<T>* obj, | (1) | (since C++11) |
template<class T> T atomic_fetch_sub(volatilestd::atomic<T>* obj, | (2) | (since C++11) |
template<class T> T atomic_fetch_sub_explicit(std::atomic<T>* obj, | (3) | (since C++11) |
template<class T> T atomic_fetch_sub_explicit(volatilestd::atomic<T>* obj, | (4) | (since C++11) |
Performs atomic subtraction. Atomically subtractsarg from the value pointed to byobj and returns the valueobj held previously. The operation is performed as if the following was executed:
Ifstd::atomic<T> has nofetch_sub member (this member is only provided forintegral,floating-point(since C++20) andpointer types exceptbool), the program is ill-formed.
Contents |
| obj | - | pointer to the atomic object to modify |
| arg | - | the value to subtract from the value stored in the atomic object |
| order | - | the memory synchronization ordering |
The value immediately preceding the effects of this function in themodification order of*obj.
Multiple threads may usestd::atomic_fetch_sub to concurrently process an indexed container.
#include <atomic>#include <iostream>#include <numeric>#include <string>#include <thread>#include <vector> constint 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 50reader 1 processed item 44reader 4 processed item 46<....>reader 0 donereader 4 donereader 3 done
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 deducedfromobj |
| atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously (public member function of std::atomic<T>)[edit] | |
(C++11)(C++11) | adds a non-atomic value to an atomic object and obtains the previous value of the atomic (function template)[edit] |
C documentation foratomic_fetch_sub,atomic_fetch_sub_explicit | |