定义
在头文件<stdatomic.h>中定义
C atomic_fetch_add(volatile A * obj,M arg);
C atomic_fetch_add_explicit(volatile A * obj,M arg,memory_order order);
作用
作用:原子替换(obj + arg -> obj), 并返回obj之前的值。
怎么理解呢?就像是i++,先返回i之后再加,只不过这里可以加arg,并且是原子操作的。我们知道i++并不是原子操作。
参数
obj和arg通过“作用”部分你应该已经知道是做什么的啦,我们主要讲一下memory_order order是什么。
第一个函数的order默认是memory_order_seq_cst;
第二个函数的order原则上可以为memory_order中的任意值,我们来看一下memory_order是什么吧~
memory_order
定义
enum memory_order {
memory_order_relaxed,
memory_order_consume,
memory_order_acquire,
memory_order_release,
memory_order_acq_rel,
memory_order_seq_cst
};
含义
typedef enum memory_order {
memory_order_relaxed, // 不对执行顺序做保证,只保证此操作是原子的
memory_order_acquire, // 本线程中,所有后续的读操作必须在本条原子操作完成后执行
memory_order_release, // 本线程中,所有之前的写操作完成后才能执行本条原子操作
memory_order_acq_rel, // 同时包含 memory_order_acquire 和 memory_order_release
memory_order_consume, // 本线程中,所有后续的有关本原子类型的操作,必须在本条原子操作完成之后执行
memory_order_seq_cst // 全部存取都按顺序执行
} memory_order;
实例
#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) {
atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); // atomic
++cnt; // undefined behavior, in practice some updates missed
}
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 10000The non-atomic counter is 9511
网友评论