You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过单原子操作实现不等比较后存储目标值?

如何用单个原子操作实现“不等则替换”逻辑

可以通过原子操作完成你描述的逻辑,你给出的代码把「读取判断」和「写入」拆成了两个独立步骤,并非原子操作,在多线程环境下会存在竞态风险。

原代码的问题

原代码中,AT.load(...) 和 AT.store(...) 都是原子操作,但整个“比较是否不等→写入”的流程不是原子的。比如两个线程同时执行这段代码:

  1. 线程A读取到原子变量值为23,判断不等于32;
  2. 线程B也读取到23,同样判断不等于32;
  3. 线程A先把值改成32;
  4. 线程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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:02:44