table of contents
std::atomic_exchange,std::atomic_exchange_explicit(3) | C++ Standard Libary | std::atomic_exchange,std::atomic_exchange_explicit(3) |
NAME¶
std::atomic_exchange,std::atomic_exchange_explicit - std::atomic_exchange,std::atomic_exchange_explicit
Synopsis¶
Defined in header <atomic>
template< class T >
T atomic_exchange( std::atomic<T>* obj,
typename std::atomic<T>::value_type desr )
noexcept;
template< class T >
T atomic_exchange( volatile std::atomic<T>*
obj,
typename std::atomic<T>::value_type desr )
noexcept;
template< class T > (1) (since C++11)
T atomic_exchange_explicit( std::atomic<T>*
obj,
typename std::atomic<T>::value_type desr,
std::memory_order order ) noexcept; (2) (since C++11)
template< class T >
T atomic_exchange_explicit( volatile
std::atomic<T>* obj,
typename std::atomic<T>::value_type desr,
std::memory_order order ) noexcept;
1) Atomically replaces the value pointed to by obj with the value of desr and
returns the value obj held previously, as if by obj->exchange(desr)
2) Atomically replaces the value pointed to by obj with the value of desr and
returns the value obj held previously, as if by obj->exchange(desr,
order)
Parameters¶
obj - pointer to the atomic object to modify
desr - the value to store in the atomic object
order - the memory synchronization ordering for this operation: all values
are
permitted.
Return value¶
The value held previously by the atomic object pointed to by obj
Example¶
A spinlock mutex can be implemented in userspace using an atomic
exchange operation,
similar to std::atomic_flag_test_and_set:
// Run this code
#include <thread>
#include <vector>
#include <iostream>
#include <atomic>
std::atomic<bool> lock(false); // holds true when locked
// holds false when unlocked
void f(int n)
{
for (int cnt = 0; cnt < 100; ++cnt) {
while(std::atomic_exchange_explicit(&lock, true,
std::memory_order_acquire))
; // spin until acquired
std::cout << "Output from thread " << n << '\n';
std::atomic_store_explicit(&lock, false, std::memory_order_release);
}
}
int main()
{
std::vector<std::thread> v;
for (int n = 0; n < 10; ++n) {
v.emplace_back(f, n);
}
for (auto& t : v) {
t.join();
}
}
Output:¶
Output from thread 2
Output from thread 6
Output from thread 7
...<exactly 1000 lines>...
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 required because T is T is deduced from the
deduced from multiple arguments atomic argument only
See also¶
atomically replaces the value of the atomic
exchange object and obtains the value held previously
(public member function of std::atomic<T>)
atomic_compare_exchange_weak
atomic_compare_exchange_weak_explicit atomically compares the value of the
atomic
atomic_compare_exchange_strong object with non-atomic argument and performs
atomic_compare_exchange_strong_explicit atomic exchange if equal or atomic
load if
(C++11) not
(C++11) (function template)
(C++11)
(C++11)
std::atomic_exchange(std::shared_ptr) specializes atomic operations for
std::atomic_exchange_explicit(std::shared_ptr) std::shared_ptr
(deprecated in C++20) (function template)
2022.07.31 | http://cppreference.com |