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 |