我正在寻找一种原子地增加短路的方法,然后返回该值.我需要在内核模式和用户模式下执行此操作,因此它在C语言下,在Linux下,在Intel 32位架构上.不幸的是,由于速度要求,互斥锁不是一个好的选择.
有没有其他方法可以做到这一点?在这一点上,似乎唯一可用的选项是内联一些程序集.如果是这样的话,有人能指出我适当的指示吗?
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中启动线程?
GCC支持原子操作:
gcc原子