原子地访问不是`std :: atomic`的变量

时间:2018-06-05 16:23:34

标签: c++ atomic

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

该功能类似于

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的签名的情况下修复此问题的任何想法?

2 个答案:

答案 0 :(得分:1)

你可以通过谨慎的演员来做到这一点:

SELECT SECOND(TIMEDIFF("13:10:11", "13:10:10")) AS Seconds; -- 1
SELECT MINUTE(TIMEDIFF("13:10:11", "13:10:10")) AS Minutes; -- 0
SELECT HOUR(TIMEDIFF("13:00:00", "14:00:00")) AS Hours; -- 1

答案 1 :(得分:1)

似乎这确实是语言上的空白,并且有一个针对c ++ 20的提案:

  

p0019R7: Atomic Ref

     

摘要:原子操作库的扩展以允许原子   适用于非原子物体的操作

     

原子引用用于对对象执行原子操作   引用的非原子对象。目的是为了原子引用   为以下方面提供最佳的原子操作实现:   非原子对象类型。所有原子操作都是通过   被引用的非原子对象上的原子引用是具有   对于引用同一对象的任何其他原子引用,   由指向该对象的指针的相等性定义。目的是为了   原子操作直接更新引用的对象。原子的   引用构造函数可以获取资源,例如从   地址分片锁的集合,以执行原子操作。   这样的原子引用对象不是无锁的,也不是无地址的。   当需要这种资源时,后续的复制和移动   构造函数和赋值运算符可以通过复制来减少开销   或移动先前获取的资源,而不是重新获取   该资源。

     

在遗留代码中引入并发性可能需要替换   使用原子操作对现有非原子对象进行操作   非原子对象不能替换为原子对象。

     

在定义明确的阶段中,可能非原子地大量使用对象   一个应用程序。强迫此类对象仅是原子的   造成不必要的性能损失。