能否通过单原子操作实现不等比较后存储目标值?
如何用单个原子操作实现“不等则替换”逻辑
可以通过原子操作完成你描述的逻辑,你给出的代码把「读取判断」和「写入」拆成了两个独立步骤,并非原子操作,在多线程环境下会存在竞态风险。
原代码的问题
原代码中,AT.load(...) 和 AT.store(...) 都是原子操作,但整个“比较是否不等→写入”的流程不是原子的。比如两个线程同时执行这段代码:
- 线程A读取到原子变量值为23,判断不等于32;
- 线程B也读取到23,同样判断不等于32;
- 线程A先把值改成32;
- 线程B接着也把值改成32。
虽然最终结果看起来没问题,但如果场景更复杂(比如目标值是动态生成的),就可能出现不符合预期的覆盖操作,而且本质上没有实现“原子性完成整个逻辑”的要求。
原子化实现方案
要原子完成“若原子变量与目标值不等则替换”的逻辑,可以利用compare_exchange_weak(或compare_exchange)来实现。这个方法会原子性地完成「比较当前值是否等于预期值→相等则替换为新值」的操作,结合循环就能实现你的需求:
use std::sync::atomic::{AtomicI32, Ordering}; static AT: AtomicI32 = AtomicI32::new(23); fn main() { let target = 32; let mut current = AT.load(Ordering::SeqCst); // 循环直到当前值等于目标值,或者成功替换 while current != target { match AT.compare_exchange_weak( current, // 预期的当前值 target, // 要替换的新值 Ordering::SeqCst, // 成功时的内存顺序 Ordering::SeqCst // 失败时的内存顺序 ) { Ok(_) => { println!("not equal, replaced"); break; } Err(new_val) => { // 其他线程修改了值,更新当前值后继续循环 current = new_val; } } } }
逻辑说明
compare_exchange_weak是原子操作,会一次性完成比较和替换动作,不会被其他线程打断;- 如果循环过程中其他线程修改了原子变量,
compare_exchange_weak会返回错误,并带回最新的变量值,我们更新current后继续尝试,直到成功替换或变量值已经等于目标值。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

