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 起)

原子地比较由 obj 指向的对象的 对象表示 (C++20 前) 值表示 (C++20 起) 与由 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 - 指向待测试和修改的原子对象的指针
expected - 指向期望在原子对象中查找到的值的指针
desired - 若原子对象的值符合预期时,将要存储到原子对象中的值
success - 比较成功时读-修改-写操作的内存同步顺序
failure - 比较失败时加载操作的内存同步顺序

返回值

比较结果:当 * obj 等于 * expected 时返回 true ,否则返回 false

注释

std::atomic_compare_exchange_weak std::atomic_compare_exchange_weak_explicit (弱版本)允许出现伪失败,即即使 * obj ! = * expected 实际相等时也可能操作失败。当在循环中进行比较交换操作时,这些弱版本在某些平台上能提供更佳性能。

当弱比较并交换需要循环而强比较并交换不需要时,除非 T 的对象表示可能包含 填充位、 (直至 C++20) 陷阱位,或为同一值提供多种对象表示(例如浮点数 NaN),否则应优先选用强比较并交换。在这些情况下,弱比较并交换通常更适用,因为它能快速收敛到某个稳定的对象表示。

对于联合体中某些成员参与值表示而其他成员不参与的位,比较并交换操作可能总是失败,因为当这些填充位不参与当前活跃成员的值表示时,它们具有不确定的值。

从不参与对象值表示的填充位将被忽略。

(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> 的公开成员函数)
原子地以非原子参数替换原子对象的值并返回原子的旧值
(函数模板)
为 std::shared_ptr 特化的原子操作
(函数模板)
C 文档 关于 atomic_compare_exchange , atomic_compare_exchange_explicit