C语言中是否有可返回旧值的atomic_set类原子设置操作?
嘿,刚好我对这类原子操作挺熟悉的!你想要的这种「原子设置新值同时返回旧值」的函数,其实很多平台和标准库都有现成实现,甚至可以用CAS手动模拟,下面给你详细说说:
实现原子设置并返回旧值的函数
1. C++ 标准库:用std::atomic::exchange
如果你用的是C++11及以上版本,标准库的std::atomic类提供了exchange成员函数,完美匹配你的需求——它会原子地把变量设置为新值,同时返回之前的旧值。
示例代码:
#include <atomic> std::atomic<int> my_var; // 定义原子变量 // 和你预期的使用方式几乎完全一致 int old_val = my_var.exchange(10);
注:std::atomic保证这个操作是线程安全的,完全满足原子性要求。
2. Linux 内核开发:用xchg函数
如果是在Linux内核环境下写代码,内核提供了xchg()宏/函数,专门处理这种原子交换操作,用法和你想要的一模一样:
#include <asm/cmpxchg.h> int my_var; int old_val = xchg(&my_var, 10); // 原子设置为10,同时返回旧值
这个函数是架构无关的,内核已经帮你处理了不同CPU的原子指令细节,直接用就行。
3. 手动用CAS模拟(兼容更多环境)
如果你的环境没有现成的exchange函数,也可以用**Compare-And-Swap(CAS)**手动实现这个逻辑——毕竟CAS是很多原子操作的基础。比如用GCC的内置函数__sync_bool_compare_and_swap:
int atomic_set(int* addr, int new_val) { int old_val; // 循环尝试CAS,直到成功(可能被其他线程打断,所以需要重试) do { old_val = *addr; // 先读取当前变量的值 } while (!__sync_bool_compare_and_swap(addr, old_val, new_val)); // CAS成功时,说明当前值还是old_val,已经被原子替换为new_val return old_val; }
如果是MSVC编译器,可以换成InterlockedCompareExchange函数来实现类似逻辑。
这样写出来的atomic_set就完全符合你想要的使用方式:int old_val = atomic_set(&my_var, 10);
内容的提问来源于stack exchange,提问作者campescassiano
相关产品推荐
相关产品推荐

