0%

重新认识原子量内存序

2020年5月22日 下午9:27

volatile:

  1. C++:
    1. 使用volatile声明变量,可以理解成把cpu和主内存之间的cache去掉了,读写都直接操作主内存
  2. Java:Java的内存屏障放在了volatile中实现
    1. 对volatile变量写操作时,会在写操作加入一条store屏障指令,将本地内存中的共享变量值刷新到主内存。
    2. 对volatile变量读操作时,会在读操作加入一条load屏障指令,从主内存中读取共享变量。

C++原子量:

  1. c++中着重强调了原子量的操作,以及原子量和mutex互斥量,一定要明白他们两得职责是不一样的
  2. 原子量的实现是靠cas操作来保证,cas其实就是redis锁.从名字上也可以看出来所谓原子量,他的操作对象是一个对象,保证了对这个对象读写的时候得原子性,即不会出现银行存取款业务类似的问题,葱这个例子中可以看出,其实仅仅实现操作的原子性使用mutex也可以代替,只不过mutex也是使用redis锁来实现,没那么直接,多封装了一层而已
  3. 原子量中内存序的作用:
    1. 原子量的操作,除了简单的保证读写当前对象得原子性,在c++中还给原子量的读写加入了内存屏障的功能,这就从屏障这个词中我们就可以看出一些端倪,相当于原先一个班的同学在一起跑来跑去得玩闹,所有的人都可以随意的找其他同学玩,这个过程相当于编译器对执行顺序进行优化,
    2. 但是这是老师在班级中加入了一个栅栏,老师希望好学生和好学生玩,在好学生之间可以随意的组合,但你坏学生不能来影响好学生,其实就是粒度更加细得分组,原先得组别唯一,现在可以为2,当然在极端情况下每个人成为一个小组,这样任何人都不会影响其他人,也不会被其他人影响。
  4. 刚刚讨论的是分组,在分组之外还有一个就是各个组别的执行顺序,刚刚学生的例子就不好表述了。
    1. 计算机redis锁的本质是解决线程唯一资源的争抢问题,它只能保证有且只有唯一的一个人获取资源,不是用来解决多个线程的执行顺序问题,就需要我们程序员给线程执行加入if条件,只有满足什么条件才能继续执行内部的代码
    2. 什么是锁、互斥量、原子操作解决不了的并发问题

总结多线程编程的造成问题的原因 与 解决方法

  1. 从问题原因下手:
    1. 如果由于编译器指令重排,我们可以使用内存屏障来解决部分重拍问题,能够保证不因为重排造成程序异常执行就行
    2. 如果我们需要多个线程进行资源的争夺,这时候就要想到加锁,加什么锁
    3. 如果我们需要规定线程得执行顺序,对不起,这个问题的程序员你分析问题,加入可执行的条件,并使用上面得准则,判断是否会被指令重排,线程交差执行影响,如果有,使用上面的方法解决,再加入if判断即可