Namespaces
Variants

std:: atomic_compare_exchange_weak, std:: atomic_compare_exchange_strong, std:: atomic_compare_exchange_weak_explicit, std:: atomic_compare_exchange_strong_explicit

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
atomic_compare_exchange_weak atomic_compare_exchange_weak_explicit atomic_compare_exchange_strong atomic_compare_exchange_strong_explicit
(C++11) (C++11) (C++11) (C++11)
Free functions for atomic flags
헤더 파일에 정의됨 <atomic>
template < class T >

bool atomic_compare_exchange_weak
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,

typename std:: atomic < T > :: value_type desired ) noexcept ;
(1) (C++11 이후)
template < class T >

bool atomic_compare_exchange_weak
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * expected,

typename std:: atomic < T > :: value_type desired ) noexcept ;
(2) (C++11 이후)
template < class T >

bool atomic_compare_exchange_strong
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,

typename std:: atomic < T > :: value_type desired ) noexcept ;
(3) (C++11 이후)
template < class T >

bool atomic_compare_exchange_strong
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * expected,

typename std:: atomic < T > :: value_type desired ) noexcept ;
(4) (C++11 이후)
template < class T >

bool atomic_compare_exchange_weak_explicit
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(5) (C++11 이후)
template < class T >

bool atomic_compare_exchange_weak_explicit
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(6) (C++11 이후)
template < class T >

bool atomic_compare_exchange_strong_explicit
( std:: atomic < T > * obj, typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(7) (C++11 이후)
template < class T >

bool atomic_compare_exchange_strong_explicit
( volatile std:: atomic < T > * obj,
typename std:: atomic < T > :: value_type * expected,
typename std:: atomic < T > :: value_type desired,

std:: memory_order success, std:: memory_order failure ) noexcept ;
(8) (C++11 이후)

object representation (until C++20) value representation (since C++20) 을 원자적으로 비교하여, obj 가 가리키는 객체와 expected 가 가리키는 객체의 표현이 비트 단위로 동일한 경우, 전자를 desired 로 대체합니다(읽기-수정-쓰기 연산 수행). 그렇지 않은 경우, obj 가 가리키는 실제 값을 * expected 에 로드합니다(로드 연산 수행).

오버로드 메모리 모델
읽기-수정-쓰기 연산 로드 연산
(1-4) std:: memory_order_seq_cst std:: memory_order_seq_cst
(5-8) success failure

이 함수들은 멤버 함수 의 관점에서 std::atomic 에 정의되어 있습니다:

1,2) obj - > compare_exchange_weak ( * expected, desired )
3,4) obj - > compare_exchange_strong ( * expected, desired )
5,6) obj - > compare_exchange_weak ( * expected, desired, success, failure )
7,8) obj - > compare_exchange_strong ( * expected, desired, success, failure )

만약 failure success 보다 강하거나 (C++17까지) 다음 중 하나인 경우 std:: memory_order_release std:: memory_order_acq_rel , 동작은 정의되지 않습니다.

목차

매개변수

obj - 테스트 및 수정할 atomic 객체에 대한 포인터
expected - atomic 객체에서 발견될 것으로 예상되는 값에 대한 포인터
desired - 예상과 일치할 경우 atomic 객체에 저장할 값
success - 비교가 성공할 경우 read-modify-write 연산에 대한 메모리 동기화 순서
failure - 비교가 실패할 경우 load 연산에 대한 메모리 동기화 순서

반환값

비교 결과: true 만약 * obj * expected 와 동일했을 경우, false 그 외의 경우.

참고 사항

std::atomic_compare_exchange_weak std::atomic_compare_exchange_weak_explicit (약한 버전)은 허위 실패(spurious failure)가 발생할 수 있습니다. 즉, * obj ! = * expected 인 경우에도 마치 서로 다른 것처럼 동작할 수 있습니다. 비교-교환 연산이 루프 내에서 사용될 때, 일부 플랫폼에서 더 나은 성능을 제공합니다.

약한 compare-and-exchange가 루프를 필요로 하고 강한 compare-and-exchange는 그렇지 않을 때, T 의 객체 표현이 패딩 비트, (C++20까지) 트랩 비트를 포함하거나 동일한 값에 대해 여러 객체 표현을 제공하는 경우(예: 부동 소수점 NaN)를 제외하고는 강한 compare-and-exchange가 바람직합니다. 이러한 경우에는 약한 compare-and-exchange가 일반적으로 안정적인 객체 표현으로 빠르게 수렴하기 때문에 효과적으로 작동합니다.

일부 멤버의 값 표현에는 참여하지만 다른 멤버의 값 표현에는 참여하지 않는 비트를 가진 union의 경우, 이러한 패딩 비트들이 활성 멤버의 값 표현에 참여하지 않을 때는 불확정 값을 가지므로 compare-and-exchange 연산이 항상 실패할 수 있습니다.

객체의 값 표현에 절대 참여하지 않는 패딩 비트는 무시됩니다.

(since C++20)

예제

비교 및 교환 연산은 종종 락프리 데이터 구조의 기본 구성 요소로 사용됩니다.

#include <atomic>
template<class T>
struct node
{
    T data;
    node* next;
    node(const T& data) : data(data), next(nullptr) {}
};
template<class T>
class stack
{
    std::atomic<node<T>*> head;
public:
    void push(const T& data)
    {
        node<T>* new_node = new node<T>(data);
        // put the current value of head into new_node->next
        new_node->next = head.load(std::memory_order_relaxed);
        // now make new_node the new head, but if the head
        // is no longer what's stored in new_node->next
        // (some other thread must have inserted a node just now)
        // then put that new head into new_node->next and try again
        while (!std::atomic_compare_exchange_weak_explicit(
                   &head, &new_node->next, new_node,
                   std::memory_order_release, std::memory_order_relaxed))
            ; // the body of the loop is empty
// note: the above loop is not thread-safe in at least
// GCC prior to 4.8.3 (bug 60272), clang prior to 2014-05-05 (bug 18899)
// MSVC prior to 2014-03-17 (bug 819819). See member function version for workaround
    }
};
int main()
{
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
}

결함 보고서

다음 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
P0558R1 C++11 정확한 타입 일치가 요구되었음
T 가 여러 인수에서 추론되었기 때문
T 는 오직
obj 에서만 추론됨

참고 항목

원자적 객체의 값을 비원자적 인자와 비교하고, 같으면 원자적 교환을 수행하거나 같지 않으면 원자적 로드를 수행함
( std::atomic<T> 의 public member function)
원자적 객체의 값을 비원자적 인자로 원자적으로 대체하고 원자적 객체의 이전 값을 반환함
(function template)
std::shared_ptr에 대한 원자적 연산 전문화
(함수 템플릿)
C 문서 for atomic_compare_exchange , atomic_compare_exchange_explicit