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

DLL函数调用周边Store/Load重排合法性及原子操作疑问

关于DLL函数调用与内存重排的疑问

我需要借助atomic_ref来保证内存操作的Store/Load顺序,但由于客户使用C++11标准,无法在产品API的头文件中直接使用atomic_ref,因此计划将相关逻辑实现为DLL中的函数。但我不确定编译器是否会对带有release语义存储的DLL函数调用前后的Store/Load操作进行重排,从而破坏预期的内存顺序。

我查阅了DLL函数调用前后Store/Load重排的合法性相关资料,确认编译器可以自由重排外部翻译单元(比如DLL)中函数调用前后的存储和加载操作。

基于此,我认为以下生产环境中的代码无法保证producer函数里的存储顺序:

#include <atomic>
#include <cassert>
#include <thread>
 
bool flag = false;
int data = 0;
 
// 假设以下命名空间中的函数实现于独立DLL
namespace defined_in_another_dll
{
    void flag_ready(bool& b)
    {
        std::atomic_ref<bool>(b).store(true, std::memory_order_release);
    }
    bool is_ready(bool& b)
    {
        return std::atomic_ref<bool>(b).load(std::memory_order_acquire);
    }
}

void producer()
{
    data = 42;
    defined_in_another_dll::flag_ready(flag); // 这个调用可能和data的赋值重排?
}
 
void consumer()
{
    while (!defined_in_another_dll::is_ready(flag));
    assert(data == 42); // 可能触发断言,因为producer中的重排!
}
 
int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
}

我的疑问是:为什么编译器可以对DLL函数调用周边的赋值操作进行重排,但直接使用atomic_ref的producer函数(如下)却被认为是合法的?谁能保证该原子存储会被始终内联,让优化器识别到编译器屏障?如果该原子存储最终编译成函数调用,那情况不就和DLL版本一样了吗?这让我十分困惑。

void producer()
{
    data = 42;
    std::atomic_ref<bool>(flag).store(true, std::memory_order_release);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:25:13