在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执行。带lock前缀的指令在操作时会锁住总线,使自身的执行即使在多处理器间也是原子性执行的。xchg指令不带lock前缀也是原子性执行,也就是说xchg执行时默认会锁内存总线。原子性操作是线程间同步的基础,linux专门定义了一种只进行原子操作的类型atomic_t,并提供相关的原子读写调用API

/**
* atomic_inc - increment atomic variable
* @v: pointer of type atomic_t
*
* Atomically increments @v by 1.
*/
static inline void atomic_inc(atomic_t *v)
{
asm volatile(LOCK_PREFIX "incl %0"
: "+m" (v->counter));
} /**
* atomic_dec - decrement atomic variable
* @v: pointer of type atomic_t
*
* Atomically decrements @v by 1.
*/
static inline void atomic_dec(atomic_t *v)
{
asm volatile(LOCK_PREFIX "decl %0"
: "+m" (v->counter));
}

带lock前缀的指令执行时才与cache有一点关系

缓存一致性,就是在多处理器系统中,每个cpu都有自己的L1 cache。很可能两个不同cpu的L1 cache中缓存的是同一片内存的内容,如果一个cpu更改了自己被缓存的内容,它要保证另一个cpu读这块数据时也要读到这个最新的。怎么保证??所以才有这个东西-----

barrier的定义:

#define barrier() __asm__ __volatile__("": : :"memory")   内存的变量值都改变了,之前存在寄存器里的变量副本无效---__volatitle__

__volatitle__是防止编译器移动该指令的位置或者把它优化掉。"memory",是提示编译器该指令对内存修改,防止使用某个寄存器中已经load 的内存的值

#ifdef CONFIG_X86_32
/*
* Some non-Intel clones support out of order store. wmb() ceases to be a
* nop for these.
*/
#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
#else
#define mb() asm volatile("mfence":::"memory")
#define rmb() asm volatile("lfence":::"memory")
#define wmb() asm volatile("sfence" ::: "memory")
#endif

64位x86,肯定有mfence、lfence和sfence三条指令,而32位的x86系统则不一定,所以需要进一步查看cpu是否支持这三条新的指令,不行则用加锁的方式来增加内存屏障。

SFENCE,LFENCE,MFENCE指令提供了高效的方式来保证读写内存的排序,这种操作发生在产生弱排序数据的程序和读取这个数据的程序之间。 
   SFENCE——串行化发生在SFENCE指令之前的写操作但是不影响读操作。 
   LFENCE——串行化发生在SFENCE指令之前的读操作但是不影响写操作。 
   MFENCE——串行化发生在MFENCE指令之前的读写操作。
sfence:在sfence指令前的写操作当必须在sfence指令后的写操作前完成。
lfence:在lfence指令前的读操作当必须在lfence指令后的读操作前完成。
mfence:在mfence指令前的读写操作当必须在mfence指令后的读写操作前完成。

重看 mb volatile atomic的更多相关文章

  1. java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析

    java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...

  2. [WAF攻防]从WAF攻防角度重看sql注入

    从WAF攻防角度重看sql注入 攻防都是在对抗中逐步提升的,所以如果想攻,且攻得明白,就必须对防有深刻的了解 sql注入的大体流程 Fuzz测试找到注入点 对注入点进行过滤检测,及WAF绕过 构建pa ...

  3. java多线程详解(8)-volatile,Atomic比较

    在变成过程中我们需要保证变量的线程安全,在java中除了使用锁机制或者Threadlocal等保证线程安全,还提供了 java.util.concurrent.atomic.Atomic*(如Atom ...

  4. java并发编程的艺术(二)---重排序与volatile、final关键字

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

  5. 重看Decorator Pattern,联想到Delegate传递及Flags Enum--欢迎拍砖!

    话说装饰模式(Decorator)的动机是“动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活.[GOF <设计模式>]”.再次学到该模式,有感 ...

  6. 重看Java教学视频时的查漏补缺

    数据类型 1.基本数据类型:四类八种. 2.数据范围与字节数不一定相关.如float为4字节表示范围比long的8字节要大. 3.浮点数默认double类型,如要用float,需加F. 4.boole ...

  7. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  8. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  9. 不得不提的volatile及指令重排序(happen-before)

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

随机推荐

  1. css实现中间横线俩边文字效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Verilog基础入门——简单的语句块编写(二)

    [题干] [代码] module top_module( input a, input b, output out ); assign out = a&b; endmodule [与或非门等] ...

  3. windows 快速安装Python3.7.2

    1.官方下载地址:https://www.python.org/downloads/release/python-372/ 其他地址:http://www.uzzf.com/soft/449550.h ...

  4. centos7安装redis6

    wget http://download.redis.io/releases/redis-6.0.6.tar.gz?_ga=2.104030464.1049731693.1595900008-1330 ...

  5. centos8平台使用pstree查看进程树

    一,pstree用途 Linux pstree命令将所有行程以树状图显示,树状图将会以 pid (如果有指定) 或是以 systemd 这个基本行程为根 (root) 说明:centos6及更旧版本为 ...

  6. mysql explain 查询处理的结果详解

    本文转自 https://blog.csdn.net/boss_way/article/details/91416887 在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这 ...

  7. 解决Java连接Oracle 12c存在的问题

    感谢作者 原文链接:https://blog.csdn.net/peng_wei_kang/article/details/80403486 1.发现项目报以下错误:   Caused by: jav ...

  8. PHP实现Bitmap的探索 - GMP扩展使用

    原文地址:https://blog.fanscore.cn/p/22/ 一.背景 公司当前有一个用户群的系统,核心功能是根据不同的条件组去不同的业务线中get符合条件的uid列表,然后存到redis中 ...

  9. Java 8新特性解读

    (四)Java 8 相关知识 关于 Java 8 中新知识点,面试官会让你说说 Java 8 你了解多少,下面分享一我收集的 Java 8 新增的知识点的内容,前排申明引用自:Java8新特性及使用 ...

  10. 转 js调用提交表单。

    今天做网银支付的时候,需要做到点击支付的时候提交订单,然后新窗口打开支付界面. 思路1:window.open(''),这个直接被pass了,因为银行的服务一般都是需要post数据的.就算是可以用ge ...