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

C++如何在不使用锁、无法改用std::atomic时避免整数比较的竞态条件

解决方案

问题根源

原有线程2的代码直接读取var1、var2属于非原子普通内存访问,和其他线程的原子写入操作之间没有同步关系,属于典型的数据竞争,会触发C++标准定义的未定义行为。

可行方案

当前代码已经使用GCC内置的原子操作API,我们可以直接复用同体系的原子读取操作实现需求,无需加锁、也无需修改变量的原有int类型:

方案1:兼容旧版GCC的实现

利用__sync_fetch_and_add加0的操作实现原子读,和现有代码的API完全兼容,操作自带全内存屏障,保证可见性:
修改线程2的代码如下:

// 原子读取var1、var2的最新值
int v1 = __sync_fetch_and_add(&var1, 0);
int v2 = __sync_fetch_and_add(&var2, 0);
var3 = v1 > v2 ? v1 : v2;

方案2:更高性能的实现(GCC 4.7及以上版本支持)

使用更轻量的__atomic_load_n配合ACQUIRE内存序,开销低于全内存屏障,性能更优:
修改线程2的代码如下:

// ACQUIRE内存序保证读取到该变量之前所有的写入结果
int v1 = __atomic_load_n(&var1, __ATOMIC_ACQUIRE);
int v2 = __atomic_load_n(&var2, __ATOMIC_ACQUIRE);
var3 = v1 > v2 ? v1 : v2;

方案合规性说明

  1. 无锁实现:原子读操作的开销极低,远低于锁的开销,完全满足性能要求
  2. 无需修改原有变量定义:两个方案都直接操作原有int类型的var1、var2,不需要改为std::atomic
  3. 消除数据竞争:所有对var1、var2的访问都变成了带同步语义的原子操作,完全消除了数据竞争
  4. 逻辑兼容:仅将原有非原子读替换为原子读,业务逻辑和原有代码完全一致,不会改变原有业务行为

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 17:24:08