C11 标准库中的原子操作

3 篇文章 0 订阅
1 篇文章 0 订阅

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标准库中的atomic原子操作

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值