使用C中的std::atomic
我有一个C库,它为原子操作定义了一堆特定于平台的宏。我如何使用使用C中的std::atomic,c,multithreading,c++11,C,Multithreading,C++11,我有一个C库,它为原子操作定义了一堆特定于平台的宏。我如何使用std::atomic作为实现 例如,C代码具有: #define mylib_atomic_int_add(_pi, _val) do_atomic_int_add(_pi, _val) int number = 0; mylib_atomic_int_add(&number, 7); extern "C" { int do_atomic_int_add(volatile int* i, volatile int
std::atomic
作为实现
例如,C代码具有:
#define mylib_atomic_int_add(_pi, _val) do_atomic_int_add(_pi, _val)
int number = 0;
mylib_atomic_int_add(&number, 7);
extern "C"
{
int do_atomic_int_add(volatile int* i, volatile int v)
{
return *i + v;
}
}
和C++平台抽象层(即,与C代码链接的C++ 11编译的静态库)为:
显然,这是不安全的,因为它不是原子的,因为int在C代码std::atomic
中声明,但在do\u atomic\u int\u add()
中是否有某种方法可以使用它?像返回std::atomic::add(*i,v)代码>
编辑:
我不知道为什么没人明白我在做什么。它基本上是如何在C++中增加一个int,它是从C函数中传递过来的。形式上的问题是:代码> STD::原子< /代码>是一种类型,其对象可以被修改为<代码>。C不调用.load
,因此它不能直接使用int
当然,您可以使用明显的实现定义extern“C”int原子负载(struct atomic int*,enum std\u memory\u order)
。基本上,您必须将std::atomic_int
包装在一个与C兼容的结构中,并转发所有方法。为什么这个问题无效
C++11原子要求使用C++11原子类型进行原子操作。您可以通过从非原子类型转换为原子类型来跳出标准,但这不是可移植代码,即使它经常工作。它甚至不是完全由C++代码有效的,更不用说C和C++的混合了。
由于这个限制,您将无法编写一个C接口的C++原子库,因为在C代码中不能声明C++ 11个原子类型。 Hans Boehm是编程语言并发特性方面最重要的权威之一,他有一个名为C++0y的提案,解释了这里的一些问题
另一种解决问题的方法 您可以完全在C语言中解决这个问题,这是最安全、最可移植的解决方案 <>在C11和C++ 11中引入母语类型之前,C和C++中原子化的最常用的方法是编译器内蕴。其中有两种变体:- ,它们基于C++11内存模型
- ,它们基于安腾ABI文档
在C++中你想使用C++的特性吗?这绝不是一个好办法。我真的不明白你的问题。我有一种感觉,
volatile
关键字并不像你想象的那样。C11有stdatomic.h
,就像C++11一样。你不应该使用一些晦涩难懂的图书馆。你可能会混淆C和C++。它们是两种不同的语言。MSVC不是符合标准的编译器。“奥拉夫”——“用C++编译C++代码,用C编译器编译C代码,通过<代码>外部”C“/Cuff>接口,C链接+ C代码+ C++ C++编译器”,有什么困难?或者,您可以使用C++编译器编译DLL或共享对象,确保库在适当的C++运行库上记录其动态依赖(IE)。
extern "C"
{
int do_atomic_int_add(volatile int* i, int v)
{
//return (*i + v);
return __sync_add_and_fetch(i,v);
}
}
extern "C"
{
int do_atomic_int_add(volatile int* i, int v)
{
//return (*i + v);
return __atomic_add_fetch(i,v, __ATOMIC_RELAXED);
}
}
extern "C"
{
int do_atomic_int_add(volatile int* i, int v)
{
int r;
#pragma omp atomic update
{ r = (*i + v); }
return r;
}
}