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

不同硬件原子操作(如__sync_fetch_and_add与__sync_lock_test_and_set)是否互斥?

不同硬件原子操作对同一变量的互斥性问题

好问题!这其实触及了硬件原子操作的核心特性——所有针对同一内存地址的原子操作,无论具体类型是CAS、FAA(Fetch-And-Add)还是Test-And-Set,都会被硬件层面保证互斥访问。下面结合你的代码和问题详细解释:

核心结论

针对同一共享变量的不同原子操作(比如你代码里的__sync_lock_test_and_set和__sync_fetch_and_add),是完全互斥的。当一个线程执行getAndSet(),另一个线程执行getAndAdd()时,硬件会确保这两个操作不会同时对value_进行修改,不会出现竞态条件导致的中间状态泄漏。

背后的原理

原子操作的本质是把“读-改-写”(或类似的复合操作)变成一个不可分割的硬件指令。为了实现这一点,CPU会通过两种机制保证同一内存地址的原子操作串行化:

  • 总线锁:当执行原子操作时,CPU会锁定系统总线,阻止其他CPU访问该内存地址,直到当前原子操作完成。
  • 缓存锁:如果目标内存地址已经被缓存在CPU的L1/L2缓存中,CPU会利用缓存一致性协议(如MESI)锁定缓存行,避免其他CPU对该缓存行的修改,从而更高效地实现原子性。

不管是哪种原子操作(CAS、FAA、Test-And-Set),只要它们操作的是同一个内存地址,硬件就会自动触发上述机制,保证这些操作互斥执行。

结合你的代码例子分析

看你实现的AtomicIntegerT类:

template<typename T> 
class AtomicIntegerT
{
    public:
        AtomicIntegerT()
            : value_(0) 
        {
        }
    
        T get() {
            return __sync_val_compare_and_swap(&value_, 0, 0);
        }   

        T getAndAdd(T x) {
            return __sync_fetch_and_add(&value_, x);
        }

        T addAndGet(T x) {
            return getAndAdd(x) + x;
        }

        T getAndSet(T newValue) {
            return __sync_lock_test_and_set(&value_, newValue);
        }

    private:
        volatile T value_; 
};

这里的几个方法:

  • get()用CAS(__sync_val_compare_and_swap)实现原子读取(因为CAS的“比较-交换”操作如果新旧值相同,本质就是原子读)
  • getAndAdd()用FAA(__sync_fetch_and_add)实现原子加法
  • getAndSet()用Test-And-Set(__sync_lock_test_and_set)实现原子赋值

当多个线程同时调用这些方法时,硬件会保证所有针对value_的原子操作都串行执行,不会出现两个操作同时修改value_的情况。比如线程A执行getAndSet(5)的同时,线程B执行getAndAdd(3),最终value_的结果要么是8(A先执行,B在5的基础上加3),要么是5(B先执行后,A直接覆盖为5)——但不管顺序如何,两个操作都是完整执行的,不会出现中间的错误值。

补充:volatile的作用

你代码里的value_用了volatile修饰,这里要注意:volatile本身不提供原子性,它的作用是告诉编译器不要对该变量的读写进行优化,确保每次读写都直接访问内存(而不是寄存器缓存)。真正的原子性是由__sync_*系列函数对应的硬件原子指令保证的,volatile只是配合原子操作,避免编译器优化破坏原子操作的正确性。

内容的提问来源于stack exchange,提问作者cserbo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:05:19