c++ - 以原子方式访问不是`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
?
解决方案
你可以通过仔细的演员来做到这一点:
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);
}