Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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 UNIX可移植原子操作_C_Concurrency_Posix_Atomic - Fatal编程技术网

C UNIX可移植原子操作

C UNIX可移植原子操作,c,concurrency,posix,atomic,C,Concurrency,Posix,Atomic,对于原子变量操作,C中是否有一种(POSIX-)可移植的方式,类似于使用pthread的可移植线程 原子操作是像“增量和获取”这样的操作,以原子方式执行,这意味着上下文切换不能干扰操作。在Linux内核空间中,我们必须键入,在Java中,我们有包 在Linux上,atomic.h文件提供原子操作,但include依赖于平台,例如,#include,在Mac OS X上无法以类似方式使用。AFAIK没有跨平台的方法来执行原子操作。那里可能有图书馆,但我不知道。不过,自己动手并不特别难 我想没有 当

对于原子变量操作,C中是否有一种(POSIX-)可移植的方式,类似于使用pthread的可移植线程

原子操作是像“增量和获取”这样的操作,以原子方式执行,这意味着上下文切换不能干扰操作。在Linux内核空间中,我们必须键入,在Java中,我们有包


在Linux上,atomic.h文件提供原子操作,但include依赖于平台,例如,
#include
,在Mac OS X上无法以类似方式使用。

AFAIK没有跨平台的方法来执行原子操作。那里可能有图书馆,但我不知道。不过,自己动手并不特别难

我想没有


当然,许可证允许的情况下,解决这个问题的一种方法是从Linux内核空间复制相关的每体系结构实现。我没有密切关注这些原语的演变,但我猜它们确实是原语,即不依赖内核中的其他服务或API。

不,POSIX没有指定任何可移植的无锁/原子操作。这就是为什么他们有pthread


您要么必须使用非标准方式,要么坚持使用ptrheads以实现可移植性。

既然您要求使用OS X:

(由于跨平台性是在这条线中提出的。)

OSX具有函数OSAtomicAdd32()和朋友。它们在“/usr/include/libkern/OSAtomic.h”中声明。 请参阅“使用原子操作”一节

对于Windows,有InterlocatedIncrement()和好友(请参阅MSDN)

与gcc内置的\uuuu sync\u fetch\u和\u add()以及好友(已在上面链接)一起,您应该 每个主要的桌面平台都有


请注意,我自己还没有使用它们,但可能会在接下来的几天内使用。

对于将来偶然发现这一点的人来说,C11原子学现在是最好的方法-我相信它们将包含在GCC 4.9中。

从C11开始,有一个可选的提供原子操作。这可以移植到任何具有C11编译器(如gcc-4.9)和此可选功能的平台

原子的存在可通过
\uu STDC\u NO\u ATOMICS\uu

atomic.c

#include <stdio.h>
#include <stdlib.h>
#ifndef __STDC_NO_ATOMICS__
#include <stdatomic.h>
#endif

int main(int argc, char**argv) {
    _Atomic int a;
    atomic_init(&a, 42);
    atomic_store(&a, 5);
    int b = atomic_load(&a);
    printf("b = %i\n", b);

    return EXIT_SUCCESS;
}

C11原子最低可运行示例

通过在Glibc2.28中添加线程,我们可以在纯C11中同时执行原子和线程

示例来自:

main.c

#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>

atomic_int acnt;
int cnt;

int f(void* thr_data)
{
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
        // for this example, relaxed memory order is sufficient, e.g.
        // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
    }
    return 0;
}

int main(void)
{
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);

    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}
可能的产出:

The atomic counter is 10000
The non-atomic counter is 8644
由于线程间对非原子变量的快速访问,非原子计数器很可能比原子计数器小

pthreads示例可在以下位置找到:


在Ubuntu18.04(glibc 2.27)中通过从源代码编译glibc进行测试:Ubuntu18.10有glibc 2.28,所以应该可以在那里工作。

你能对此进行扩展吗?最小可运行C11原子+线程示例:有一些GCC内置程序,.Nice,限于GCC,但这对我来说是好的。这里是新的gcc:但如果我们坚持使用Glibc2.27,stdatomic会与
pthreads
一起工作吗?Glibc2.28随Ubuntu 18.10或19.04一起提供
gcc -std=c11 main.c -pthread
./a.out
The atomic counter is 10000
The non-atomic counter is 8644