Memory Barriers and Volatile Variables
这两种方法都是从内存限制方面入手的同步工具
需先了解:
- 为了更好的性能优化,编译器经常都会重组汇编指令,以使得命令管道得到最大化的利用
- 由于上述所述的优化,编译器对指令的重组,设计到内存数据的操作,可能会导致产生不正确数据的问题
- 同时,编译器是不可能检测到所有设计到内存数据的操作,因此,为了得到编译器的优化,一些问题是肯定会有
对于上述的问题,就有以下两种方法来解决
Memory Barriers
内存屏障
- 这是一种非阻塞式的同步工具
- 这个工具确保了内存数据的操作肯定是按正确的顺序执行
大致的工作原理是
- 在代码中合适的地方,调用一个方法,产生一个 memory barrier, 假设为 fence
- 以这个 fence 为界,fence 之后的代码,总是在 fence 之前的代码全部执行完后再执行
比如:
- 可以在这个 fence 之前,使用多个线程读取多个文件到内存;而在 fence 之后,对这多个文件的内容进行合并的操作
- 而合并操作肯定需要在文件读取完之后才能进行,但由于使用的是多线程读取,我们并不能确定多个文件都读取完成的时间
- 此时,利用上面的 fence, 读操作都在 fence 之前,合并操作都在 fence 之后,就保证了合并操作肯定是在全部读操作完成之后进行
Volatile Variables
直译:不稳定的变量
需先了解:
- 编译器出于优化的原因,通常会将变量的值从内存加载到寄存器(registers)中
- 对于其他线程(假设 T2s)需要用到的变量,事情就变得不那么简单了。上述的优化可能会导致 T2s 不能观察到变量值的变化,这就导致了数据不一致的问题了
- 这里需要接受一个可能的知识点是:寄存器中的值变化行为与内存中值变化的行为是不一致的
于是,使用 volatile
变量,可以迫使程序在每次使用到变量时,都需要重新从内存中读取