C11 标准库中的原子操作atomic
只是对于嵌入式编程
c语言中避免不了原子操作atomic,防止多线程中数据竞争。
C11 atomic variables and the kernel
Atomic primitives in the kernel
Atomic usage patterns in the kernel
Semantics and Behavior of Atomic and Bitmask Operations
参考链接:C11标准库中的atomic原子操作
stdatomic.h
路径/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdatomic.h
__STDC_NO_ATOMICS__
检查是否支持stdatomic
原子数据类型
atomic_char, atomic_int, atomic_size_t
初始化原子变量可以使用如下函数
- ATOMIC_VAR_INIT
- atomic_init
- ATOMIC_FLAG_INIT
操作原子变量则使用如下函数,保证原子性 - atomic_store
- atomic_load
- atomic_exchange
- atomic_compare_exchange_strong, atomic_compare_exchange_weak
- atomic_fetch_add, atomic_fetch_sub, atomic_fetch_or, atomic_fetch_xor, atomic_fetch_and
- atomic_flag_test_and_set
- atomic_flag_clear
关于编译
-std=c11
例子
启动偶数个线程,每个线程循环固定次数对同一个atomic_int变量操作,一半进行加一操作,另一半进行减一操作。
#ifdef __STDC_NO_ATOMICS__ // since gcc 4.9
#error "Do not support C11 atomic"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdatomic.h>
#include <pthread.h>
#define N_THREADS 8
#define LOOP_NUM 10000
typedef struct _job {
atomic_int *pval;
int *p_normal;
int id;
} job;
static void *worker(void *arg)
{
job *p_job = arg;
if (p_job->id & 0x1) {
for (int i = 0; i < LOOP_NUM; i++) {
usleep(100);
atomic_fetch_sub(p_job->pval, 1);
*(p_job->p_normal) = *(p_job->p_normal) - 1;
}
} else {
for (int i = 0; i < LOOP_NUM; i++) {
usleep(100);
atomic_fetch_add(p_job->pval, 1);
*(p_job->p_normal) = *(p_job->p_normal) + 1;
}
}
return NULL;
}
int main(int argc, char**argv)
{
pthread_t threads[N_THREADS];
job jobs[N_THREADS];
atomic_int val = ATOMIC_VAR_INIT(0);
int normal_val = 0;
for (int i = 0; i < N_THREADS; i++) {
job *p_job = &jobs[i];
p_job->pval = &val;
p_job->p_normal = &normal_val;
p_job->id = i;
pthread_create(threads + i, NULL, worker, p_job);
}
for (int i = 0; i < N_THREADS; i++)
pthread_join(threads[i], NULL);
printf("normal: %d\n", normal_val);
if (atomic_load(&val) != 0) {
printf("test fail !!!\n");
} else {
printf("test pass.\n");
}
return 0;
}
请参考
- C11 Lock-free Stack
- An implementation of the C11 interface
- Toward a Better Use of C11 Atomics – Part 1
- Toward a Better Use of C11 Atomics – Part 2
引用原文:C11标准库中的atomic原子操作