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

C++中条件依赖atomic变量的双原子变量更新线程安全问题

std::atomic多线程同步问题解答

示例代码

// constructing atomics
#include <iostream>       // std::cout
#include <atomic>         // std::atomic
#include <thread>         // std::thread
#include <vector>         // std::vector

std::atomic<int> a1{0};
std::atomic<int> a2{0};

void count1m (int id) {
         double local = id;
         double local2 = id*3;
         if(local > a1) {      // a1 is an atomic variable so will reading it in if condition be atomic across threads or not?
                a1 = local;
                a2 = local2;
        }
 };

int main ()
{
        std::vector<std::thread> threads;
        std::cout << "spawning 20 threads that count to 1 million...\n";
        for (int i=20; i>=0; --i) {
           threads.push_back(std::thread(count1m,i));
        }
        
        for (auto& th : threads) th.join();
        std::cout << "a1 = " << a1 << std::endl;                                                                                                  
}

疑问解答

  • 问题1:在if(local > a1)中,读取atomic变量a1的操作是否具备跨线程原子性?
    是的,std::atomic类型的默认读取操作是原子的。这个读取操作会被CPU处理为不可分割的指令,不会出现读取到一半被其他线程打断、拿到中间无效值的情况,跨线程环境下读取结果是可靠的。

  • 问题2:若线程t1正执行该if判断,线程t2是否会等待t1完成a1的更新?
    不会。std::atomic的读取操作本身不会触发线程阻塞或同步等待机制。t1读取a1的同时,t2可以毫无阻碍地读取甚至修改a1,两者的操作是并行的,没有强制等待的逻辑。

  • 问题3:是否可能出现一个线程更新a2、另一个线程更新a1的情况?
    完全可能。当前代码里,if判断→更新a1→更新a2这一整套逻辑不是原子操作,三个步骤之间可能被其他线程打断。比如:

    1. 线程A通过if(local > a1)判断,更新了a1,但还没来得及更新a2;
    2. 此时线程B读取到A更新后的a1,若B的local值更大,就会通过自己的if判断,开始更新a1;
    3. 这时就会出现线程A在更新a2,线程B在更新a1的场景,最终导致a1和a2的值不匹配(a1是B的local,a2是A的local2)。

如果要避免这种不一致,你需要把判断+更新的逻辑封装成原子操作:

  • 方案一:使用std::atomic::compare_exchange_strong配合循环,实现基于CAS的原子更新;
  • 方案二:用std::mutex给整个if代码块加锁,确保同一时间只有一个线程执行判断和更新操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:20:46