shared_ptr_atomic

shared_ptr_atomic (shared_ptr 원자 접근 함수)

<memory> 헤더에 정의되어 있어요. std::shared_ptr 객체에 대한 원자 접근을 위해 std::atomic_load, std::atomic_store 등에 대응하는 전용 오버로드 함수들이에요. C++11부터 도입, C++20에서 deprecated, C++26에서 제거됐어요.

출처: cppreference

본문

template< class T >
bool atomic_is_lock_free( const std::shared_ptr<T>* p );                            // (1)
template< class T >
std::shared_ptr<T> atomic_load( const std::shared_ptr<T>* p );                      // (2)
template< class T >
std::shared_ptr<T> atomic_load_explicit( const std::shared_ptr<T>* p, std::memory_order mo );  // (3)
template< class T >
void atomic_store( std::shared_ptr<T>* p, std::shared_ptr<T> r );                   // (4)
template< class T >
void atomic_store_explicit( std::shared_ptr<T>* p, std::shared_ptr<T> r, std::memory_order mo ); // (5)
template< class T >
std::shared_ptr<T> atomic_exchange( std::shared_ptr<T>* p, std::shared_ptr<T> r );  // (6)
template< class T >
std::shared_ptr<T> atomic_exchange_explicit( std::shared_ptr<T>* p, std::shared_ptr<T> r, std::memory_order mo ); // (7)
template< class T >
bool atomic_compare_exchange_weak( std::shared_ptr<T>* p, std::shared_ptr<T>* expected, std::shared_ptr<T> desired );  // (8)
template< class T >
bool atomic_compare_exchange_strong( std::shared_ptr<T>* p, std::shared_ptr<T>* expected, std::shared_ptr<T> desired );  // (9)
template< class T >
bool atomic_compare_exchange_strong_explicit( std::shared_ptr<T>* p, std::shared_ptr<T>* expected,
    std::shared_ptr<T> desired, std::memory_order success, std::memory_order failure );  // (10)
template< class T >
bool atomic_compare_exchange_weak_explicit( std::shared_ptr<T>* p, std::shared_ptr<T>* expected,
    std::shared_ptr<T> desired, std::memory_order success, std::memory_order failure );  // (11)

(모두 C++11, deprecated in C++20, removed in C++26)

여러 실행 스레드가 동기화 없이 같은 std::shared_ptr 객체에 접근하고 그 중 하나라도 shared_ptr의 비-const 멤버 함수를 사용하면, 그 모든 접근이 이 함수들(대응하는 원자 접근 함수의 오버로드)을 통해 수행되지 않는 한 데이터 경쟁이 발생해요.

shared_ptr의 제어 블록은 스레드 안전하므로, 서로 다른 std::shared_ptr 객체는 내부적으로 같은 제어 블록을 공유하고 있어도 operator=이나 reset 같은 가변 연산을 여러 스레드가 동시에 수행해도 안전해요.

  • (1) p가 가리키는 공유 포인터에 대한 원자 접근이 lock-free인지 결정.
  • (2) atomic_load_explicit(p, std::memory_order_seq_cst)와 동등.
  • (3) p가 가리키는 공유 포인터를 반환.
  • (4)(5) p가 가리키는 공유 포인터에 r을 원자적으로 저장.
  • (6)(7) p가 가리키던 값을 반환하면서 r을 저장하는 원자 교환.
  • (8)-(11) pexpected가 가리키는 공유 포인터를 비교해 동등하면 desired*p에 대입하고 true, 아니면 *p*expected에 대입하고 false.

p가 널 포인터이면 이 함수들의 동작은 모두 미정의예요.

주의 (Notes)

이 함수들은 보통 포인터 값을 키로 사용하는 전역 해시 테이블에 저장된 뮤텍스로 구현돼요. C++20부터는 std::atomic<std::shared_ptr> 특수화가 이 함수들을 대체했고, C++26에서 제거됐어요.

더 알아보기 (Learn more)

cppreference