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

原子操作内存序:relaxed能否避免函数重复调用,是否需Acquire/Release?

原子变量内存序与函数重复调用的同步必要性

问题描述

为避免need_close()函数被重复调用,是否需要通过Acquire/Release内存序建立同步关系?

示例代码

#include <iostream>
#include <atomic>
#include <random>
#include <thread>
int need_close(){
   random_device rd;
   std::mt19937 gen(rd());
   uniform_int_distribution<int> distribute(0, 2);
   return distribute(gen);
}
void invoke(std::atomic<bool>& is_close){
    if(is_close.load(std::memory_order::relaxed)){  // #1
        return;
    }
    auto r = need_close();
    if(r==0){
        is_close.store(true,std::memory_order::relaxed);
    }
}
int main(){
    std::atomic<bool> is_close{false};
    std::thread t1([&](){
        for(auto i = 0; i<100000;i++)
        invoke(is_close);
    });
    std::thread t2([&](){
        for(auto i = 0; i<100000;i++)
        invoke(is_close);
    });
    t1.join();
    t2.join();
}

当前代码使用relaxed内存序操作原子变量is_close,预期逻辑是:当某一线程将is_close设为true后,其他线程读取到该值就不再调用need_close()。但存在疑问:relaxed内存序是否会导致编译器/CPU指令重排,把#1处的load操作移到need_close()调用之后,进而导致函数被不必要地重复调用?

结论与解释

必须使用Acquire/Release内存序来约束指令重排,才能保证预期逻辑生效。

为什么relaxed内存序不可行?

relaxed内存序仅保证原子操作本身的原子性,不提供任何跨线程的同步约束,甚至允许同一线程内的指令重排——只要重排不违反单线程的程序语义。

具体到这段代码,编译器完全可能将need_close()的调用重排到is_close.load()之前执行:单线程视角下,不管先执行判断还是先调用函数,最终的控制流结果看起来一致(比如如果load返回true就直接return,但重排后先调用函数再判断,单线程内不会出现逻辑矛盾),这种重排是符合relaxed内存序规则的。但在多线程场景下,这会导致即使is_close已经被其他线程设为true,当前线程仍可能先执行need_close(),违背了预期逻辑。

正确的内存序用法

给is_close的加载和存储操作分别指定acquire和release内存序:

  • release存储:保证当前线程中所有在store之前的操作,不会被重排到store之后。
  • acquire加载:保证当前线程中所有在load之后的操作,不会被重排到load之前。

修改后的invoke函数代码:

void invoke(std::atomic<bool>& is_close){
    if(is_close.load(std::memory_order::acquire)){  // Acquire内存序
        return;
    }
    auto r = need_close();
    if(r==0){
        is_close.store(true,std::memory_order::release);  // Release内存序
    }
}

这样就能确保#1处的load操作一定在need_close()调用之前执行,当读取到is_close == true时,会直接return,不会触发不必要的函数调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:22:35