1. 概念
原子操作是指不被打断的操作,即它是最小的执行单位。最简单的原子操作就是一条条的汇编指令(不包括一些伪指令,伪指令会被汇编器解释成多条汇编指令)。在 linux 中原子操作对应的数据结构为 atomic_t,定义如下:

typedef struct {    int counter;} atomic_t;

本质上就是一个整型变量,之所以定义这么一个数据类型,是为了让原子操作函数只接受 atomic_t 类型的操作数,如果传入的不是 atomic_t 类型数据,在程序编译阶段就不会通过;另一个原因就是确保编译器不会对相应的值进行访问优化,确保对它的访问都是对内存的访问,而不是对寄存器的访问。2. 赋值操作
ARM 处理器有直接对内存地址进行赋值的指令(STR)。

#define atomic_set(v,i)    (((v)->counter) = (i))

3. 读操作
用 volatile 来防止编译器对变量访问的优化,确保是对内存的访问,而不是对寄存器的访问。

#define atomic_read(v)    (*(volatile int *)&(v)->counter)

4. 加操作
使用独占指令完成累加操作。

static inline void atomic_add(int i, atomic_t *v){    unsigned long tmp;    int result;    // 使用独占指令读取,然后执行加操作,独占写失败时就重新执行    __asm__ __volatile__("@ atomic_add\n""1:    ldrex    %0, [%3]\n""    add    %0, %0, %4\n""    strex    %1, %0, [%3]\n""    teq    %1, #0\n""    bne    1b"    : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)    : "r" (&v->counter), "Ir" (i)    : "cc");}

5. 减操作
对比加操作减操作的代码可以看出,它们非常的相似,其实不同的地方就一句,所以现在最新的内核源码中已经使用宏定义 ATOMIC_OP(op, c_op, asm_op) 来重写了这部分代码。

static inline void atomic_sub(int i, atomic_t *v){    unsigned long tmp;    int result;    // 使用独占指令读取,然后执行减操作,独占写失败时就重新执行    __asm__ __volatile__("@ atomic_sub\n""1:    ldrex    %0, [%3]\n""    sub    %0, %0, %4\n""    strex    %1, %0, [%3]\n""    teq    %1, #0\n""    bne    1b"    : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)    : "r" (&v->counter), "Ir" (i)    : "cc");}

6. 其他操作
类似的原子操作函数还有一些,比如 atomic_XXX_return、atomic_cmpxchg、atomic_clear_mask,以及在此基础上实现的 atomic_inc、atomic_dec、atomic_XXX_and_test、atomic_XXX_return等。以上代码都是针对 SMP 处理器的实现方式,针对非 SMP 处理器,由于不存在其他核心的抢占,所以只需要防止其他进程抢占即可实现原子操作,例如加操作

static inline int atomic_sub_return(int i, atomic_t *v){    unsigned long flags;    int val;    // 通过关闭中断防止其他进程打断代码的执行    raw_local_irq_save(flags);    val = v->counter;    v->counter = val -= i;    // 恢复中断原始的状态    raw_local_irq_restore(flags);    return val;}

7. 总结
原子性操作的实现需要具体体系结构相关的指令集的支持。

c++ 原子操作 赋值_原子操作原理相关推荐

  1. 全局变量中断原子操作_原子操作原理分析

    原子操作原理分析 概念 原子操作是指不被打断的操作,即它是最小的执行单位.最简单的原子操作就是一条条的汇编指令(不包括一些伪指令,伪指令会被汇编器解释成多条汇编指令).在 linux 中原子操作对应的 ...

  2. c++ 原子操作 赋值_高级Java开发工程师带你走进原子操作,一篇文章搞清楚原子操作...

    原子特性: 原子是最小的粒子,不可再分 这并不是一个化学课,而是巧妙的借用了化学上的一个概念,即原子是最小的粒子,不可再分;原子操作也是不能再分的操作; 为了能把这个讲明白,下文基本都是大白话,其实J ...

  3. c++ 原子操作 赋值_请问c++如何实现原子性操作?

    原子性,也就是要么全部做完,要么全部不做 在多进程(线程)访问资源时,能够确保所有其他的进程(线程)都不在同一时间内访问相同的资源.原子操作(atomic operation)是不需要同步,这是Jav ...

  4. c++ 原子操作 赋值_多线程操作可见性

    可见性:让一个线程对共享变量的修改,能够及时的被其他线程看到,java中首先想到的就是volatile volatile关键字 Java内存模型中规定: 1.对某个volatile 字段的写操作hap ...

  5. 5.3.6 原子操作对非原子的操作排序

    5.3.6 原子操作对非原子的操作排序 当你使用一个普通的非原子bool类型来替换清单5.12中的x(就如同你下面看到的代码),行为 和替换前完全一样. 清单5.13 使用非原子操作执行序列 #inc ...

  6. c++ 原子操作 赋值_5.2 C++中的原子操作和原子类型

    5.2 C++中的原子操作和原子类型 原子操作 是个不可分割的操作. 在系统的所有线程中,你是不可能观察到原子操作完成了一半这种情况的: 它要么就是做了,要么就是没做,只有这两种可能. 如果从对象读取 ...

  7. 竞态条件的赋值_《Java并发编程实战》读书笔记一:基础知识

    一.线程安全性 一个对象是否是需要是线性安全的,取决于它是否需要被多个线程访问 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要额外的同步,这个 ...

  8. java 反射set方法赋值_反射 根据属性名获得属性set方法并为set方法赋值

    /** * * @param key 属性名 * @param value 属性值 * @param o 要封装的对象 */ public static void setObject(String k ...

  9. element label动态赋值_浅析 vuerouter 源码和动态路由权限分配

    背景 上月立过一个 flag,看完 vue-router 的源码,可到后面逐渐发现 vue-router 的源码并不是像很多总结的文章那么容易理解,阅读过你就会发现里面的很多地方都会有多层的函数调用关 ...

最新文章

  1. 向基于Linux的Oracle RAC 10g集群添加新节点
  2. Source Insight主题推荐和显示属性设置方法
  3. 276. Paint Fence
  4. 3-1:常见任务和主要工具之软件包管理
  5. neostrack服务器无响应,捷安特GPS码表NeosTrack试用评测
  6. DiskFileItemFactory类的使用
  7. python emf转gif_python – 将EMF / WMF文件转换为PNG / JPG
  8. 去除Word中的红色或则绿色波浪线
  9. 信息化促进价值链的构造与协同
  10. c# winform 任务栏显示和隐藏
  11. the little schemer 笔记(6)
  12. 如何做出优雅的过渡效果? Dotween插件的简单介绍及示例代码
  13. 读写三维数据.stl文件
  14. 【心理咨询师考试笔记】基础理论(六)——心理咨询概论
  15. 遇到的问题--docker---gitlab---k8s---error pulling image configuration: Get https://production.cloudflare.
  16. 第9个HttpClient 例子,HttpClient+jsoup 扩展获取网站信息
  17. android bitmap设置透明度,Android 设置图片 Bitmap任意透明度
  18. eps8266自动重启问题, Soft WDT reset (已解决)
  19. 活在IT,半路捡起硌脚的石子
  20. Java 8 字符串和时间相互转换

热门文章

  1. C#PDF转Word
  2. .NET 4.0 任务(Task)
  3. Microsoft Visual Studio 正忙
  4. MemCached配置与缓存知识概述
  5. Android 创建其它应该程序的上下文对象
  6. 四道微软面试经典算法题
  7. PHP源码之数组的内部实现
  8. Vue中splice的使用:删除 替换 添加
  9. python效率提升_Python GUI开发,效率提升10倍的方法!
  10. zend framework1.12 没找到php.exe,请加一个zend framework的有关问题