首页 > 解决方案 > 以原子方式访问不是`std::atomic`的变量

问题描述

我们有一些旧代码正在更新以使用更现代的 c++。它以前依靠(令人讨厌的)视觉工作室扩展volatile来原子地访问变量。

该功能类似于

T ReadAq(T* val)
{
    return *(volatile T*)val;
}

请注意,T对于我们支持的体系结构,它已适当对齐且足够小,从而能够在不翻录的情况下进行单次读取。

写入变量有类似的功能,变量的所有使用都通过这些函数之一。

而且我真的不想改变它的签名(因为这对所有调用者来说都是一个巨大的改变)所以我希望能够做类似的事情:

T ReadAq(T* val)
{
    return std::atomic_read(val, std::memory_order_acquire);
}

但似乎标准中不存在这样的功能 - 所有原子操作都在 std::atomic 类型上。关于是否可以在不更改签名的情况下解决此问题的任何想法ReadAq

标签: c++atomic

解决方案


你可以通过仔细的演员来做到这一点:

template<class T>
T ReadAq(T* val) {
    using AT = std::atomic<T>;
    static_assert(sizeof(T) == sizeof(AT), "Incompatible layout.");
    static_assert(alignof(T) == alignof(AT), "Incompatible layout.");
    return reinterpret_cast<AT*>(val)->load(std::memory_order_acquire);
}

推荐阅读