命名空间
变体
操作

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

来自 cppreference.cn
< 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)
Hazard 指针
原子类型
(C++11)
(C++20)
原子类型的初始化
(C++11)(C++20 中已弃用)
(C++11)(C++20 中已弃用)
内存顺序
(C++11)(C++26 中已弃用)
原子操作的自由函数
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) (since C++11) (始于 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) (since C++11) (始于 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) (since C++11) (始于 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) (since C++11) (始于 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) (since C++11) (始于 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) (since C++11) (始于 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) (since C++11) (始于 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) (since C++11) (始于 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) 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_releasestd::memory_order_acq_rel 之一,则行为未定义。

内容

[编辑] 参数

obj - 指向要测试和修改的原子对象的指针
expected (期望值) - 指向期望在原子对象中找到的值的指针
desired (期望值) - 如果要与期望值相同则存储在原子对象中的值
success (成功) - 如果比较成功,则读取-修改-写入操作的内存同步顺序
failure (失败) - 如果比较失败,则加载操作的内存同步顺序

[编辑] 返回值

比较的结果:如果 *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_exchange, atomic_compare_exchange_explicit