命名空间
变体
操作

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

来自 cppreference.com
< cpp‎ | atomic
 
 
并发支持库
线程
(C++11)
(C++20)
this_thread 命名空间
(C++11)
(C++11)
(C++11)
协作式取消
互斥
(C++11)
通用锁管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
条件变量
(C++11)
信号量
闩锁和屏障
(C++20)
(C++20)
期货
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
危险指针
原子类型
(C++11)
(C++20)
原子类型的初始化
(C++11)(在 C++20 中弃用)
(C++11)(在 C++20 中弃用)
内存顺序
原子操作的自由函数
atomic_compare_exchange_weakatomic_compare_exchange_weak_explicitatomic_compare_exchange_strongatomic_compare_exchange_strong_explicit
(C++11)(C++11)(C++11)(C++11)
原子标志的自由函数
 
定义于头文件 <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 起)

原子地比较 对象表示(直至 C++20)值表示(自 C++20 起)obj 指向的对象与由 expected 指向的对象,若它们按位相等,则将前者替换为 desired(执行读-改-写操作)。否则,将由 obj 指向的实际值加载到 *expected 中(执行加载操作)。

 重载  内存模型,用于
 读-改-写 操作  加载操作
(1-4) std::memory_order_seq_cst  std::memory_order_seq_cst 
(5-8) 成功 失败

这些函数是根据 成员函数 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_releasestd::memory_order_acq_rel 之一,则行为未定义。

目录

[编辑] 参数

obj - 指向要测试和修改的原子对象的指针
expected - 指向预期在原子对象中找到的值的指针
desired - 若原子对象与预期值一致,则要存储在原子对象中的值
成功 - 若比较成功,则为读-改-写操作的内存同步顺序
失败 - 若比较失败,则为加载操作的内存同步顺序

[编辑] 返回值

比较的结果:若 *obj 等于 *expected,则为 true,否则为 false

[编辑] 注意

std::atomic_compare_exchange_weakstd::atomic_compare_exchange_weak_explicit(弱版本)允许虚假失败,即即使 *obj != *expected 相等,也表现得如同它们不相等。当比较并交换在循环中时,它们在某些平台上会产生更好的性能。

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

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

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

(自 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_exchangeatomic_compare_exchange_explicit