gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:11:22 25 4
gpt4 key购买 nike

我正在寻找一种方法来自动递增一个 short,然后返回该值。我需要在内核模式和用户模式下都这样做,所以它在 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 一起工作。

主.c

#include <assert.h>
#include <pthread.h>
#include <stdlib.h>

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

反汇编分析:How do I start threads in plain C?

在 Ubuntu 18.10、GCC 8.2.0、glibc 2.28 中测试。

C11 _Atomic

在 5.1 中,上述代码适用于:

_Atomic int global = 0;
global++;

并且在 glibc 2.28 中添加了 C11 threads.h,它允许您在没有 POSIX 的情况下在纯 ANSI C 中创建线程,最小可运行示例:How do I start threads in plain C?

关于c - 如何在 C 中进行原子增量和获取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2353371/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com