Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C中的std::atomic_C_Multithreading_C++11 - Fatal编程技术网

使用C中的std::atomic

使用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

我有一个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 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文档
GCC、Clang和Intel编译器以及其他编译器都支持这两种编译器(IBM当然支持,Cray大多数支持,但至少有一个bug,可能还有PGI)。我不使用Windows,但我知道MSVC有一些用于原子的编译器内部函数

此外,至少有两种具有许可证的C原子的开源实现:

此外,OpenMP 3+使您能够使用C89代码中的原子,但我不知道MSVC是否充分支持它

最后,将以完全ISO标准的方式完美地解决您的问题。然而,编译器支持目前相当有限。我在GCC 5+和新款Clang中使用过这些功能,也许还有Intel 16,但我不希望MSVC支持它们

代码 我从值中删除了volatile,因为它不起任何作用。除了关闭C++名称的限制之外,不需要使用“代码>外部”C“/CODE”,因为没有实现使用C++。因为您没有指定内存排序要求,所以我假设放松(无序)原子就足够了

__同步版本 __原子版本 OpenMP版本
在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;
    } 
}