当前位置:  开发笔记 > 编程语言 > 正文

如何在C中进行原子增量和获取?

如何解决《如何在C中进行原子增量和获取?》经验,为你挑选了2个好方法。

我正在寻找一种原子地增加短路的方法,然后返回该值.我需要在内核模式和用户模式下执行此操作,因此它在C语言下,在Linux下,在Intel 32位架构上.不幸的是,由于速度要求,互斥锁不是一个好的选择.

有没有其他方法可以做到这一点?在这一点上,似乎唯一可用的选项是内联一些程序集.如果是这样的话,有人能指出我适当的指示吗?



1> Ciro Santill..:

GCC __atomic_*内置插件

从GCC 4.8开始,__sync内置插件已被弃用,以支持__atomic内置插件:https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/_005f_005fatomic-Builtins.html

它们实现了C++内存模型,并std::atomic在内部使用它们.

以下POSIX线程示例++在x86-64上始终失败,并始终使用_atomic_fetch_add.

main.c中

#include 
#include 
#include 

enum CONSTANTS {
    NUM_THREADS = 1000,
    NUM_ITERS = 1000
};

int global = 0;

void* main_thread(void *arg) {
    int i;
    for (i = 0; i < NUM_ITERS; ++i) {
        __atomic_fetch_add(&global, 1, __ATOMIC_SEQ_CST);
        /* This fails consistently. */
        /*global++*/;
    }
    return NULL;
}

int main(void) {
    int i;
    pthread_t threads[NUM_THREADS];
    for (i = 0; i < NUM_THREADS; ++i)
        pthread_create(&threads[i], NULL, main_thread, NULL);
    for (i = 0; i < NUM_THREADS; ++i)
        pthread_join(threads[i], NULL); 
    assert(global == NUM_THREADS * NUM_ITERS);
    return EXIT_SUCCESS;
}

编译并运行:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out ./main.c -pthread
./main.out

反汇编分析:如何在普通C中启动线程?

测试在Ubuntu 18.10,GCC 8.2.0,glibc 2.28.

C11 _Atomic

在5.1中,上面的代码适用于:

_Atomic int global = 0;
global++;

并且threads.h在glibc 2.28中添加了C11 ,它允许您在没有POSIX的情况下在纯ANSI C中创建线程,最小可运行示例:如何在普通C中启动线程?



2> dicroce..:

GCC支持原子操作:

gcc原子

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有