Scroll to navigation

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