std::atomic...ub_explicit(3)
π
std::atomic...ub_explicit(3) π
okay bestie, welcome to the std::atomic...ub_explicit(3) page from the C++ Standard Libary manual β yes, βLibaryβ is literally how itβs spelled in the header, and we are keeping it π. This is the group chat for std::atomic_fetch_sub and std::atomic_fetch_sub_explicit, and they are iconic little atomic subtractors.
πΈ NAME πΈ
std::atomic_fetch_sub,std::atomic_fetch_sub_explicit β thatβs the whole name, bestie. Both functions, one page, no cap.
β¨ SYNOPSIS β¨
Defined in header <atomic>.
(1) β since C++11:
template< class T >
T atomic_fetch_sub( std::atomic<T>* obj,
typename std::atomic<T>::difference_type arg ) noexcept;
(2) β since C++11:
template< class T >
T atomic_fetch_sub( volatile std::atomic<T>* obj,
typename std::atomic<T>::difference_type arg ) noexcept;
(3) β since C++11:
template< class T >
T atomic_fetch_sub_explicit( std::atomic<T>* obj,
typename std::atomic<T>::difference_type arg,
std::memory_order order ) noexcept;
(4) β since C++11:
template< class T >
T atomic_fetch_sub_explicit( volatile std::atomic<T>* obj,
typename std::atomic<T>::difference_type arg,
std::memory_order order ) noexcept;
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:
1,2) obj->fetch_sub(arg)
3,4) obj->fetch_sub(arg, order)
bestie, careful: ifstd::atomic<T>has nofetch_submember (this member is only provided for integral, floating-point (since C++20) and pointer types exceptbool), the program is ill-formed. π
π«Ά PARAMETERS π«Ά
objβ pointer to the atomic object to modifyargβ the value to subtract from the value stored in the atomic objectorderβ the memory synchronization ordering
π RETURN VALUE π
The value immediately preceding the effects of this function in the modification order of *obj. literally the previous value, periodt π
π§ EXAMPLE π§
Multiple threads may use std::atomic_fetch_sub to concurrently process an indexed container.
// Run this code
#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
π DEFECT REPORTS π
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
- DR
P0558R1β applied toC++11.- Behavior as published:
exact type match was required because T is only deduced from obj - Correct behavior:
T was deduced from multiple arguments
- Behavior as published:
π SEE ALSO π
fetch_subβ atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously (public member function ofstd::atomic<T>)atomic_fetch_add,atomic_fetch_add_explicit(C++11) β adds a non-atomic value to an atomic object and obtains the previous value of the atomic (function template) (C++11)- C documentation for
atomic_fetch_sub,atomic_fetch_sub_explicit
mwah π this page is from http://cppreference.com, dated 2024.06.10, and the page tag is std::atomic...ub_explicit(3). bye bestie, go subtract atomically and slay β¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms