compare_exchange_weak
是 C++ 标准库 <atomic>
中 std::atomic
类的一个成员函数,用于执行原子的比较和交换(Compare-And-Swap,CAS)操作。该操作是无锁编程中的核心操作之一,在多线程环境下保证数据的原子性更新,避免使用传统锁机制带来的性能开销。
功能概述
compare_exchange_weak
函数会将原子变量的当前值与一个期望值进行比较,如果两者相等,则将原子变量的值更新为指定的新值;如果不相等,则将期望值更新为原子变量的当前值。该函数可能会出现伪失败的情况,即即使原子变量的当前值与期望值相等,操作也可能返回 false
,但这并不影响其在循环中重试以达到最终的更新目的。
函数原型
bool compare_exchange_weak( T& expected, T desired,
std::memory_order success,
std::memory_order failure );
参数解释
expected
:一个引用,指向存储期望值的变量。如果比较操作成功,原子变量会被更新为desired
;如果失败,expected
会被更新为原子变量的当前值。desired
:当原子变量的当前值等于expected
时,要赋给原子变量的新值。success
:std::memory_order
类型的值,指定当比较和交换操作成功时所使用的内存序。内存序决定了原子操作在不同线程之间的可见性和顺序关系。failure
:std::memory_order
类型的值,指定当比较和交换操作失败时所使用的内存序。
期望值更新的作用
当比较和交换操作失败时,compare_exchange_weak 会将期望值更新为原子变量的当前值。这一设计非常有用,因为它允许调用者在操作失败后立即获取到原子变量的最新值,从而可以根据这个新值来决定下一步的操作,例如继续重试或者采取其他策略。在循环重试的场景中,更新期望值可以确保下一次比较和交换操作是基于最新的值进行的,避免了不必要的错误。
返回值
true
:表示比较和交换操作成功,原子变量的值已被更新为desired
。false
:表示比较和交换操作失败,expected
已被更新为原子变量的当前值。
示例代码
#include <iostream>
#include <atomic>
#include <thread>
std::atomic<int> atomicValue(0);
void increment() {
int expected = 0;
int newVal = 1;
while (!atomicValue.compare_exchange_weak(expected, newVal)) {
// 处理失败情况,更新 expected 的值
expected = atomicValue.load();
}
std::cout << "Value updated successfully." << std::endl;
}
int main() {
std::thread t(increment);
t.join();
std::cout << "Final value: " << atomicValue.load() << std::endl;
return 0;
}
代码解释
- 在
increment
函数中,使用compare_exchange_weak
函数尝试将atomicValue
的值从expected
(初始值为 0)更新为newVal
(值为 1)。 - 如果操作失败,
expected
会被更新为atomicValue
的当前值,然后在循环中继续尝试,直到操作成功。 - 最终输出更新后的
atomicValue
的值。
使用场景
compare_exchange_weak
常用于无锁数据结构(如无锁队列、无锁栈等)的实现,以及需要高效并发更新共享数据的场景。由于其可能出现伪失败,通常需要在循环中使用,以确保最终的更新操作成功。与 compare_exchange_strong
相比,compare_exchange_weak
在某些硬件平台上性能更高,因为它的实现更接近硬件的原子操作。