如何使用 C++11 实现指向整数的指针的原子增量<atomic>?
How to implement an atomic increment of a pointer to an integer using C++11 <atomic>?
在将一些Windows C++代码移植到iOS时,我需要提供Win32的long InterlockedIncrement(long *p)
调用的实现。使用<libkern/OSAtomic.h>
中定义的函数,这就足够容易了。
然而,我想知道是否可以只使用C++11工具(主要是<atomic>
)以与操作系统无关的方式编写它。我想出了这个,我不确定它是否能实现我想要的:
inline long InterlockedIncrement(long* p)
{
std::atomic<long&> atomicP(*p);
return ++atomicP;
}
这行得通吗?这足够好吗?这两行不是原子的,但增量应该是原子的,这是这里的关键。
我发现的<atomic>
的所有使用示例都是不同的,其中std::atomic<T>
是直接定义和使用的。在这里,我想使用一个现有的长变量,调用者通过地址传递给我。我找不到这样的例子。
编辑:Clang 3.2(在Xcode 4.x中)无法编译++atomicP
,错误为"不能增加类型std::atomic<long&>
的值"(也不能增加atomicP += 1
)。
正确的方法是什么?
再次编辑:指针实现正在编译。。。
inline long InterlockedIncrement(long* p)
{
std::atomic<long*> atomicP(p);
return ++(*atomicP);
}
但我担心这不起作用,因为我不增加原子类型,而是增加指针指向的值,这不是原子类型。
您的示例实现是每次从指针构建一个新的原子。这不是std::atomic的预期用途,我不相信它能按照您的意愿工作。
据我所知,实现您想要做的事情(以独立于平台的方式消除对InterlockdIncrement的依赖)的唯一方法是将您当前调用Win32"interlock"调用的变量的所有声明替换为它们的std::原子版本。然后,您可以删除互锁调用,并使用正则值语义来原子地修改变量。无论如何,这更可读(将来也更可维护)。
我理解您希望保留现有的(经过良好测试的)代码,但我认为在您的情况下不能。
__atomic_add_fetch
GCC扩展
在GCC 4.8中,C++标准库实现了带有GCC内置__atomic_add_fetch
的std::atomic::operator++
,因此您可以编写:
inline long InterlockedIncrement(long* p)
{
return __atomic_add_fetch(p, 1, __ATOMIC_SEQ_CST);
}
我不确定clang,但似乎有一些选择,比如__c11_atomic_fetch_add
http://clang.llvm.org/docs/LanguageExtensions.html
正如其他人所提到的,参数p
本身必须是std::atomic
才能仅使用标准库方法:将指针转换为原子指针没有帮助,因为原子指针只作用于指针,而不作用于它所指向的内容。
我相信您可以使用atomic_fetch_add
操作。看看这里的例子。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中